将表中的日期与 TableAU 中的多个日期范围进行比较:构建 WHERE 语句

Posted

技术标签:

【中文标题】将表中的日期与 TableAU 中的多个日期范围进行比较:构建 WHERE 语句【英文标题】:Compare Date from TableB to several date ranges in TableA: Building WHERE statement 【发布时间】:2014-11-16 03:37:49 【问题描述】:

我想从 TableB 中选择开始日期在 VacationHistory (TableA) 表中的日期范围之一之间的项目。

假设我有具有开始和结束日期值的 VacationHistory 数据表 (TableA)。我需要做的是将另一个数据表(TableB)中的日期与VacationHistory(TableA)中的日期范围之间进行比较。因此,如果 VacationHistory 数据表中有三个条目,我会这样做:

SELECT *
FROM TableB WHERE (
        (DateInTableB BETWEEN '2014-10-21' AND '2014-10-27')
     OR (DateInTableB BETWEEN '2014-11-05' AND '2014-11-13')
     OR (...)
)

但是,如何在此 WHERE 子句中使用 VacationHistory 表中的所有日期范围构建此查询。我想我无话可说BETWEEN IN (....)

我尝试过的方法是构建一串完整的 where 子句::

DECLARE @listStr VARCHAR(MAX)
SELECT  @listStr = COALESCE(@listStr + ' OR ' , '') + 
    ('DateInTableB BETWEEN ''' + CAST(StartDate AS NVARCHAR) + ''' AND ' 
              + '''' + CAST(EndDate AS NVARCHAR) + '''') 
FROM VacationHistory
SELECT @listStr

@listStr 有这样的东西:DateInTableB BETWEEN '2014-11-05' AND '2014-11-13' OR DateInTableB BETWEEN '2014-10-21' AND '2014-10-27'

但是,我认为我不能直接在 where 子句中使用 @listStr,如下所示:

WHERE (@listStr)

我能做些什么呢?

【问题讨论】:

【参考方案1】:

如果您只想在 TableB 中的任何日期范围内查找开始日期的行,您可以使用相关exists

select * 
from TableB b 
where exists (
    select 1 
    from TableA a
    where b.StartDate between a.StartDate and a.EndDate
)

Sample SQL Fiddle

【讨论】:

哇,太好了。这正是我所需要的。非常感谢!【参考方案2】:
SELECT *
FROM TableB
inner join 
(
select Min(StartDate) StartDate, Max(EndDate) EndDate From TableA
) A
on  DateInTableB between A.StartDate and A.EndDate

【讨论】:

【参考方案3】:

您需要一个简单的INNER JOIN

SELECT DISTINCT b.id,
       b.StartDate
FROM   TableB b
       JOIN TableA a
         ON b.StartDate BETWEEN a.StartDate AND a.EndDate 

或者

SELECT *
FROM   TableB
       INNER JOIN (SELECT Min(StartDate) StartDate,
                          Max(EndDate)   EndDate
                   FROM   TableA) A
               ON DateInTableB BETWEEN A.StartDate AND A.EndDate 

如果你想以你尝试过的方式得到答案,那么你需要Dynamic SQL

declare @sql nvarchar(max)
DECLARE @listStr VARCHAR(MAX)

SELECT  @listStr = COALESCE(@listStr + ' OR ' , '') + 
    ('DateInTableB BETWEEN ''' + CAST(StartDate AS NVARCHAR) + ''' AND ' 
              + '''' + CAST(EndDate AS NVARCHAR) + '''') 
FROM VacationHistory


set @sql = 'SELECT *
FROM TableB where '+@listStr+''

exec sp_executesql @sql

【讨论】:

请注意,如果与 TableA 中的多个日期范围匹配,则使用内连接的查询将从 TableB 返回相同的 id,除非您添加 distinct 或 group by 子句。

以上是关于将表中的日期与 TableAU 中的多个日期范围进行比较:构建 WHERE 语句的主要内容,如果未能解决你的问题,请参考以下文章

SQL从日期范围内的同一表中的不同记录中获取多个项目的总和(ORACLE)

使用 Athena / Presto 从多个表返回 SQL 数据,受 1 个表中的日期范围限制

如何从日期范围查询中查找表中的一组缺失日期

Oracle Join 表与第一个表中的日期范围和第二个表中的日期

从 Postgres 中的非结束日期范围列表中查找未覆盖的日期范围

为文本表更改 Tableau 的自动标签