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ď č. 1Navrhujem 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
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