sql重复联合所有

sql重复联合所有,sql,sql-server,Sql,Sql Server,对于学校,我有一个datetime视图,其中包含从2000年1月1日到2999年12月31日的日期列表。现在,我想创建一个视图,在该视图中,我使用case when将假日添加到此表中。有些假期是在同一天,这就是为什么我需要使用工会所有。这将获得以下代码: select * from ( Select date as d, case -- New Years Day when date_tru

对于学校,我有一个datetime视图,其中包含从2000年1月1日到2999年12月31日的日期列表。现在,我想创建一个视图,在该视图中,我使用case when将假日添加到此表中。有些假期是在同一天,这就是为什么我需要使用工会所有。这将获得以下代码:

select *
from (
Select date as d,
                case
                --  New Years Day
                    when date_trunc('year',d) = d then 'NH - New Years Day'
               else NULL
                end as holiday_name
from dim_date t
union all
Select date as d,
                case
               --  Christmas Break School
                    when d between '2020-12-19' and '2021-01-03' then 'Christmas Break School'
                    when d between '2021-12-25' and '2021-01-09' then 'Christmas Break School'
                    else NULL
                end as holiday_name
from dim_date t
union all
Select date as d,
                case
               --  Carnaval
                    when d between '2021-02-11' and '2021-02-16' then 'Carnaval'
                    else NULL
                end as holiday_name
from dim_date t
) as x
where 1+1 = 2 
and x.holiday_name is not null
这使得我在新年那天和圣诞节假期学校都有一次吵架。 问题是:我需要在每个假期都重复下面的部分,让它变得很长

Select date as d,
                case
               --  Carnaval
                    when d between '2021-02-11' and '2021-02-16' then 'Carnaval'
                    else NULL
                end as holiday_name
from dim_date t

这将使查询非常长,因为我有超过50个假期的列表。有什么方法可以缩短这个时间吗?

如果数据被组织到虚拟(或物理)表中,这样做可以简化查询的创建和执行

;with
dim_date_cte([date]) as (
    select cast('20000101' as date) union all
    select '20000102' union all
    select '20000103' union all
    select '20000104' union all
    select '20000105'),
holidays_cte(start_dt, end_dt, holiday_name) as (
    select '20000101', '20000101', 'New Year'
    union all
    select '20000103', '20000104', 'Jan 3-4 Holdiay')
select dc.[date], hc.holiday_name
from dim_date_cte dc
     left join holidays_cte hc on dc.[date] between hc.start_dt and hc.end_dt;
输出

date        holiday_name
2000-01-01  New Year
2000-01-02  NULL
2000-01-03  Jan 3-4 Holdiay
2000-01-04  Jan 3-4 Holdiay
2000-01-05  NULL

在这里使用
UNION ALL
无疑会让人觉得您为解决方案选择了错误的路径。为什么不简单地用另一个表来记录假期日期,然后从你的
dim_date
表中加入
?为什么你看所有年份的新年,而只看一年的课间休息?因为假期不能在一个表中,所以它们是第一次提到的演员。学校的课间休息一年又一年都在休息,“因为假期不能在一张桌子上”为什么不呢?这是存储数据的合理位置。不是在一堆
大小写表达式中,它们永远不会很好地伸缩。您有一个名为dim_date的日期表,您有一个大约50个假期的列表,您希望将它们彼此关联起来。这就是关系数据库所擅长的。如果您坚持认为没有假日表是可能的(为什么?),那么组织代码以在虚拟表(或公共表表达式)中表示假日仍然是有意义的。