繁体   English   中英

在列中的日期值之后查找下一个日期 (SQL Server 2008)

[英]Find next date after date value in column (SQL Server 2008)

我正在尝试使用 2 个表OrdersRepairs构建查询。 目标是找到任何特定客户的订单日期之后的第一个维修日期,如果订单之间没有维修,则为“空”。 以下是每个的当前列:

CustomerID LocationID SaleDate
-------------------------------
1          1b         1/10/2019
1          1b         2/23/2019
1          1c         1/29/2019
2          2a         3/01/2019
2          2a         3/25/2019

CustomerID LocationID RepairDate
--------------------------------
1          1b         2/25/2019
1          1c         2/13/2019
1          1c         2/27/2019
2          2a         3/03/2019
2          2a         3/17/2019

这是预期的结果。 有任何想法吗? 出于某种原因,我尝试过的一切似乎都不起作用

CustomerID LocationID SaleDate  RepairDate
-------------------------------------------
1          1b         1/10/2019 null
1          1b         2/23/2019 2/25/2019
1          1c         1/29/2019 2/13/2019
2          2a         3/1/2019  3/3/2019
2          2a         3/25/2019 null

使用outer apply

select o.*, r.*
from orders o outer apply
     (select top (1) r.*
      from repairs r
      where r.customerId = o.customerId and
            r.locationid = o.locationid and
            r.RepairDate > o.SaleDate
      order by r.RepairDate
     ) r;

注意:您指定您希望客户的第一个维修日期。 但是,数据表明您真正指的是客户/位置组合。

编辑:

感谢您设置 SQL Fiddle。 这就澄清了这个问题。 我认为这个调整做了你想要的:

——来自 Gordon Linoff 的回答

select o.*, r.*
from (select o.*,
             lead(saledate) over (partition by customerid order by saledate) as next_salesdate
      from orders o
     ) o outer apply
     (select top (1) r.*
      from repairs r
      where r.customerId = o.customerId and
            r.locationid = o.locationid and
            r.RepairDate > o.SaleDate and
            (r.RepairDate < o.next_salesdate or o.next_salesdate is null)
      order by r.RepairDate
     ) r;

是db<>小提琴。

这有点冗长,但这是我想到的最好的方法,以防止相同的维修与所有以前的销售相匹配,我认为这是 Gordon Linoff 简单得多的答案的一个问题。 我已将您的两个表合并到一个事件日志中,然后使用 row_number 窗口函数来识别影响同一客户和位置的事件序列。 在这里试试

WITH eventlog
     AS (SELECT *,
                Row_number()
                  OVER(
                    partition BY customerid, locationid
                    ORDER BY eventdate) AS seq
         FROM   (SELECT customerid,
                        locationid,
                        saledate AS eventdate,
                        's'      AS type
                 FROM   orders
                 UNION
                 SELECT customerid,
                        locationid,
                        repairdate AS repairdate,
                        'r'        AS type
                 FROM   repairs) a)
SELECT s.customerid,
       s.locationid,
       s.eventdate AS saledate,
       r.eventdate AS repairdate
FROM   eventlog s
       LEFT JOIN eventlog r
              ON s.seq + 1 = r.seq
                 AND s.customerid = r.customerid
                 AND s.locationid = r.locationid
                 AND r.type = 'r'
WHERE  s.type = 's';  

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM