/ / Ako môžem vylúčiť víkendy a sviatky v sql server query - sql-server, dátum

Ako môžem vynechať víkendy a sviatky v dotazoch servera sql - sql-server, dátum

I "m vytvorenie dotazu, ktorý upraví dátum okrem sviatkov a víkendov.

Príklady údajov:

Adjusted Date | Adjusted Date(Excluding Holidays and weekends)

02/06/16 | 02/09/16

Na mojom príklade, Dátum je víkend a upravenýdátum sa stáva 9. februárom, pretože 8. február je sviatok, takže je potrebné ho upraviť tak, aby upravený dátum bol pracovným dňom. V súčasnosti mám oddelenú tabuľku všetkých víkendov a sviatkov vo fiškálnom roku.

select  case when (
select   count(dbo.WeekendsHoliday.[Weekends & Holidays])
from     dbo.WeekendsHoliday
where    dbo.WeekendsHoliday.[Weekends & Holidays]
= case when convert(time, [Time Received]) > convert(time, "5:00:00 PM")
then dateadd(day, 1, [Date Received])
else [Date Received]
end
) > 0
then case (datename(DW,
case when convert(time, [Time Received]) > convert(time, "5:00:00 PM")
then dateadd(day, 1, [Date Received])
else [Date Received]
end))
when "Saturday"
then dateadd(day, 2,
case when convert(time, [Time Received]) > convert(time, "5:00:00 PM")
then dateadd(day, 1, [Date Received])
else [Date Received]
end)
else dateadd(day, 1,
case when convert(time, [Time Received]) > convert(time, "5:00:00 PM")
then dateadd(day, 1, [Date Received])
else [Date Received]
end)
end
end as [Adjusted Date Excluding holidays and weekends]

Čo sa tu deje, ak je sviatok 2 po sebe idúce dni (štvrtok a piatok), upravený dátum bude sobota, ktorá je stále neplatná, pretože je to víkend.

Upravený dátum je alias

Naozaj potrebujem vašu pomoc. Vďaka

odpovede:

2 pre odpoveď č. 1

Navrhujem vytvoriť funkciu, ktorá rekurzívneoveriť nasledujúci pracovný deň na základe tabuľky, ktorá obsahuje víkendy a sviatky. Výhodou tohto prístupu je, že je to opakovane použiteľná funkcia vždy, keď ju potrebujete.

Táto funkcia prijíma dátum a čas. (Na základe kódu vo vašej otázke), ak je čas po 17:00, pridá sa deň. Potom pokračujte v kontrole, či dátum nie je cez víkendy alebo sviatky, kým nenájdete nasledujúci pracovný deň:

CREATE FUNCTION dbo.adjustedDate(@dateReceived DATETIME, @timeReceived TIME)
RETURNS DATETIME
AS
BEGIN
DECLARE @adjustedDate DATETIME = @dateReceived

-- Verify time to add 1 day to @adjustedDate
IF @timeReceived IS NOT NULL
IF @timeReceived > CONVERT(TIME, "5:00:00 PM")
SET @adjustedDate = DATEADD(DAY, 1, @adjustedDate)

-- Continue adding 1 day to @adjustedDate recursively until find one date that is not a weekend or holiday
IF EXISTS(SELECT [Weekends & Holidays]
FROM dbo.WeekendsHoliday
WHERE [Weekends & Holidays] = @adjustedDate)
SET @adjustedDate = dbo.adjustedDate(DATEADD(DAY, 1, @adjustedDate), NULL)

RETURN @adjustedDate
END

2 pre odpoveď č. 2

to trvá dátumy vo vašom WeekendsHoliday tabuľke a nájde nasledujúci deň, že nie je v rovnakej tabuľke.

potom ste opustili spojenie s výsledkom, aby ste dostali nasledujúci deň, ak je dátum z tabuľky v tabuľke WeekendsHoliday

DECLARE @WeekendsHoliday TABLE ([Weekends & Holidays] DATETIME)
INSERT INTO @WeekendsHoliday VALUES
("2016-03-05"),
("2016-03-06"),
("2016-03-07"),
("2016-03-12"),
("2016-03-13");

DECLARE @Schedule TABLE ([WorkDay] DATETIME)
INSERT INTO @Schedule VALUES
("2016-03-02"),
("2016-03-03"),
("2016-03-05"),
("2016-03-07"),
("2016-03-08"),
("2016-03-11"),
("2016-03-12");

WITH RecursiveCTE AS
(
SELECT
[Weekends & Holidays],
DATEADD(d, 1, [Weekends & Holidays]) AS [Next Day]
FROM
@WeekendsHoliday
UNION ALL
SELECT
cte.[Weekends & Holidays],
DATEADD(d, 1, [Next Day])
FROM
RecursiveCTE cte
WHERE
[Next Day] IN (SELECT [Weekends & Holidays] FROM @WeekendsHoliday)
),
AggregateCTE AS (
SELECT
[Weekends & Holidays],
MAX([Next Day]) [Next Day]
FROM
RecursiveCTE
GROUP BY
[Weekends & Holidays]
)
SELECT
s.WorkDay,
COALESCE(cte.[Next Day], s.WorkDay) AS [Adjusted Date Excluding holidays and weekends]
FROM
@Schedule s
LEFT JOIN AggregateCTE cte ON s.[WorkDay] = cte.[Weekends & Holidays]

používaš INNER JOIN AggregateCTE namiesto LEFT JOIN AggregateCTE Ak chcete zobraziť iba dátumy, ktoré sú upravené. i "d tiež odporúčame filtrovanie WITH RecursiveCTE ak je to možné, dátum začiatku a dátum ukončenia.


2 pre odpoveď č. 3

SQL Fiddle Demo

SELECT MIN(allDays.dte)
FROM (
SELECT "2015-01-01" + INTERVAL ones.a + 10*tens.a + 100*hundred.a DAY dte
FROM
(SELECT 0 a UNION SELECT 1 a UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 ) ones,
(SELECT 0 a UNION SELECT 1 a UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 ) tens,
(SELECT 0 a UNION SELECT 1 a UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 ) hundred
WHERE "2015-01-01" + INTERVAL ones.a + 10*tens.a + 100*hundred.a DAY  <  "2016-01-01"
) allDays
LEFT JOIN holidays H
ON allDays.dte = H.holydate
WHERE
H.holydate IS NULL
AND allDays.dte >= "2015-12-12"  -- HERE go your Source DATE

VÝKON

| MIN(allDays.dte) |
|------------------|
|       2015-12-14 |  --Because 12 and 13 are holidays

vysvetlí

Najprv je potrebné vytvoriť zoznam pre všetky dni. Tu generujem poddotaz na zoznam všetkých dní od 2015, budete sa musieť prispôsobiť veľkým rozsahom.

SELECT "2015-01-01" + INTERVAL ones.a + 10*tens.a + 100*hundred.a DAY dte
FROM
(SELECT 0 a UNION SELECT 1 a UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 ) ones,
(SELECT 0 a UNION SELECT 1 a UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 ) tens,
(SELECT 0 a UNION SELECT 1 a UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 ) hundred
WHERE "2015-01-01" + INTERVAL ones.a + 10*tens.a + 100*hundred.a DAY  <  "2016-01-01"

Potom vykonáte a left join zistiť, či DÁTUM je sviatok

LEFT JOIN holidays H
ON allDays.dte = H.holydate

Nakoniec vyberte menší dátum, ktorý nie je dovolenkou

WHERE H.holydate IS NULL           -- NULL mean doesnt have a match in the holiday table
AND allDays.dte >= "2015-12-12"  -- HERE go your Source DATE

1 pre odpoveď č. 4

Vytvoril som veľmi jednoduchý kód, ktorý budevylúčiť prázdniny a sobotu nedeľa pri pridávaní dní vo vašom dátume. Po prvé, musíte vytvoriť prázdninový stôl pre to potom môžete urobiť s nižšie kód. Dúfam, že budete mať svoj výsledok s mojím kódom, pretože som to vytvoril a funguje správne.

    ;WITH Numbers AS
(
SELECT 1 AS value
UNION ALL
SELECT value + 1 AS value
FROM Numbers
WHERE Numbers.value <= 99
)
SELECT FinalTable.FromDate,FinalTable.AddedDays,FinalTable.AdjustedDate
FROM (
SELECT Final.*,ROW_Number() OVER (ORDER BY (SELECT NULL)) AS AddedDays
FROM (
SELECT tbl.FromDate,CASE WHEN DATENAME(dw,tbl.AdjustedDate) = "Saturday" THEN 0
WHEN DATENAME(dw,tbl.AdjustedDate) = "Sunday" THEN 0
WHEN tbl.AdjustedDate in (SELECT Holiday_Date FROM Holiday) THEN 0
ELSE 1 END AS LogicNumber ,tbl.days, tbl.AdjustedDate
FROM (
SELECT @FromDate AS FromDate, DATEADD(DAY,num,@FromDate) AS AdjustedDate, num AS days
FROM (
SELECT ROW_Number() OVER (ORDER BY (SELECT NULL)) AS num  FROM Numbers
) t
WHERE num <= 100
) tbl
)Final
WHERE LogicNumber = 1
)FinalTable
WHERE AddedDays = @days

Umožňuje povedať @FromDate = "2017-12-30" A 1. január 2018 je dovolenka, ktorá je prítomná v Holiday Table a musíme pridať 10 dní, t. J

VÝKON

FromDate    | AddedDays | AdjustedDate
2017-12-30  | 10        | 2018-01-15