如何找到两个日期之间的所有日期并检查是否有"holiday"?

How to find all dates between two dates and check if there is a "holiday"?

我想找到两个日期列之间的所有日期,然后检查每一行的这两个日期之间是否有假期。
我还有另一个 table,其中列出了我可以加入的所有假期。
如果日期之间有任何假期,则为假期放置一个是的标志。 最好的方法是什么?
我的数据库是雪花。

Table1

id   Country  Date1        Date2
1    DE       2018-12-23   2018-12-30
2    DE       2019-08-01   2019-08-09
...
3    DE       2019-04-28   2019-05-02

Table 2

Country  Date        Holiday
DE       2018-12-25  Christmas
DE       2019-05-01  Labor Day

我希望结果看起来像

结果:

id  Country     Date1       Date2         is_holiday
1   DE          2018-12-23   2018-12-30   Yes
2   DE          2019-08-01   2019-08-09   No
...
3   DE          2019-04-28   2019-05-02   Yes

暗示你有一个 tally table(它在 TSQL 上,但你可以使用类似的东西)在一个范围内的每一天和假期然后:

SELECT E.*, 
    TOTAL_DAYS = (SELECT COUNT(CONVERT(INT,holiday,112)) AS D FROM CALENDAR C WHERE holiday = 0 AND C.dateValue BETWEEN begDATE AND endDATE)
FROM yourTable E

与 table Table_DateFromTo:


并且 table Table_HolidayDates:


您可以 运行 这样的查询:

    SELECT DateFrom as MinDate,
        DateTo as MaxDate,
      (SELECT  count(*)
        FROM    Table_HolidayDates
        WHERE   Date >= A.DateFrom
        AND     Date < A.DateTo) as HolidayCount
  FROM Table_DateFromTo A


它为您提供以下输出:

您可以找到给定日期的假期 DISTINCT COUNT 并从实际天差中减去它。以下查询应该执行您想要的操作:,

CREATE TABLE #table1 (Date1 DATE, Date2 DATE)
INSERT INTO #table1 VALUES
('2018-12-23','2018-12-30'),
('2019-04-28','2019-05-02')
CREATE TABLE #table2 (Country VARCHAR(2), [Date] DATE, Holiday VARCHAR(25))
INSERT INTO #table2 VALUES
('DE','2018-12-25','Christmas'),
('DE','2019-05-01','Labor Day'),
('DE','2019-04-29','SoMe Holiday1')


SELECT Date1,Date2,DATEDIFF(DAY,Date1,Date2)-T.holidays [Days (Excl Holidays)], T.holidays AS [Number_of_Holidays]
FROM #table1
CROSS APPLY (VALUES((SELECT COUNT(DISTINCT Holiday) FROM #table2 WHERE[Date] BETWEEN Date1 and Date2) ) ) AS T(Holidays)

结果如下,

Date1       Date2       Days (Excl Holidays)  Number_of_Holidays
2018-12-23  2018-12-30  6                     1
2019-04-28  2019-05-02  2                     2

使用表的 LEFT JOIN 和分组依据:

select 
  t1.id, t1.Country, t1.date1, t1.date2,
  case count(t2.holiday) when 0 then 'No' else 'Yes' end is_holiday 
from table1 t1 left join table2 t2
on t1.country = t2.country and t2.date between t1.date1 and t1.date2
group by t1.id, t1.Country, t1.date1, t1.date2

参见 demo(对于 MySQL,但由于我使用标准 SQL,我相信它也适用于 Snowflake)。
结果:

| id  | Country | date1               | date2               | is_holiday |
| --- | ------- | ------------------- | ------------------- | ---------- |
| 1   | DE      | 2018-12-23 00:00:00 | 2018-12-30 00:00:00 | Yes        |
| 2   | DE      | 2019-08-01 00:00:00 | 2019-08-09 00:00:00 | No         |
| 3   | DE      | 2019-04-28 00:00:00 | 2019-05-02 00:00:00 | Yes        |