【问题标题】:Joining two tables with date ranges连接两个具有日期范围的表
【发布时间】:2017-08-17 17:40:06
【问题描述】:

我有两个包含开始日期和结束日期的 SQL 表。

 Table 1: Name, AddedDate
 Table 2: Name, RemovedDate

我希望加入这两个表并将数据转储到一个临时表中,以显示何时从列表中添加和删除名称。

同一个名字可能被多次添加和删除。

所需的输出示例

- Name, AddedDate, RemovedDate
- Jane, 2017-02-01, 2017-02-03
- Bill, 2017-01-28, (blank)
- Mike, 2017-01-15, 2017-01-19
- Jane, 2017-01-13, 2017-01-14

有人可以帮忙吗?谢谢。

【问题讨论】:

标签: mysql sql-server


【解决方案1】:

另一个选项是 OUTER APPLY(如果是 SQL Server)

示例

Declare @Table1 table (Name varchar(25),AddedDate date)
Insert Into @Table1 Values
('Jane', '2017-02-01'),
('Bill', '2017-01-28'),
('Mike', '2017-01-15'),
('Jane', '2017-01-13')

Declare @Table2 table (Name varchar(25),RemovedDate date)
Insert Into @Table2 Values
('Jane', '2017-02-03'),
('Mike', '2017-01-19'),
('Jane', '2017-01-14')


Select A.Name
      ,A.AddedDate
      ,B.RemovedDate
 From  @Table1 A
 Outer Apply (
                Select RemovedDate=min(RemovedDate)
                 From  @Table2
                 Where Name=A.Name
                  and  RemovedDate>=A.AddedDate
             ) B

退货

Name    AddedDate   RemovedDate
Jane    2017-02-01  2017-02-03
Bill    2017-01-28  NULL
Mike    2017-01-15  2017-01-19
Jane    2017-01-13  2017-01-14

【讨论】:

  • 从输出中导出输入的工作做得很好。 +1
  • @SqlZim 几乎掌握了复制和粘贴。毕竟,我是一名编码员 :)
  • @CST1126 很高兴它有帮助
  • @CST1126 以防万一。 OUTER APPLY 将包含空值,而 CROSS APPLY 将排除它们,即 Bill
【解决方案2】:

使用相关子查询仅考虑上次添加(并可能删除)名称的时间...

select Name,
       AddedDate,
      (select max(RemovedDate)
         from table_2
        where Name=q1.Name
          and RemovedDate >= q1.AddedDate) as RemovedDate
 from (select Name,
              max(AddedDate) as AddedDate
         from table_1
        group by name) as q1
order by AddedDate desc,
         Name;

每次添加和删除名称时都显示相同的相关子查询方法...

select Name,
       AddedDate,
      (select min(RemovedDate)
         from table_2
        where Name=q1.Name
          and RemovedDate >= t1.AddedDate) as RemovedDate
 from table_1 t1
order by AddedDate desc,
         Name;

【讨论】:

    【解决方案3】:

    你可以在名字上使用左连接

      select t1.name, t1.AddedDate, t2.RemovedDate
      from table1 t1 
      left join table2 t2 on t1.name = t2.name 
      order by name, t1.AddedDate, t2.RemovedDate
    

    【讨论】:

      【解决方案4】:

      对于 SQL Server 使用下面的脚本

      ;WITH CTE
      AS
      (
          SELECT
              SeqNo = ROW_NUMBER() OVER(PARTITION BY T1.Name ORDER BY T1.AddedDate DESC,T2.RemovedDate DESC)
              T1.Name,
              T1.AddedDate,
              T2.RemovedDate
              FROM Table1 T1 
                  LEFT JOIN Table2 T2
                      ON LTRIM(RTRIM(T1.name)) = LTRIM(RTRIM(T2.name))
      )
      SELECT
          *
          FROM CTE
          WHERE SeqNo = 1
      

      如果您想要名称的所有记录,例如,如果多次添加和删除名称并且您想要每个日期,那么只需在没有

      的情况下执行
      WHERE SeqNo = 1
      

      部分

      【讨论】:

        猜你喜欢
        • 2022-08-17
        • 2015-10-31
        • 2018-12-19
        • 2020-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-15
        相关资源
        最近更新 更多