sql-server 在SQL中计算并查找一周中的第二天

i34xakig  于 2022-10-31  发布在  其他
关注(0)|答案(2)|浏览(146)

假设我有这样的数据
| 客户ID|事务处理日期(_D)|
| - -|- -|
| 第001号|2022年9月1日|
| 第001号|2022年9月4日|
| 第001号|二十二年九月十四日|
| 二号|2022年9月3日|
| 二号|2022年9月1日|
| 二号|二十二年九月十八日|
| 二号|二十二年九月二十日|
| C 003号|2022年9月2日|
| C 003号|二十二年九月二十八日|
| C 004色|2022年9月8日|
| C 004色|二十二年九月十八日|
但是我无法找到基于Trans_date的第一个和第二个事务。我希望结果如下所示:
| 客户ID|跨周(_W)|第一个|第二个|
| - -|- -|- -|- -|
| 第001号|三十五个|三十五个|三十七人|
| 第001号|三十五个|三十五个|三十七人|
| 第001号|三十七人|三十五个|三十七人|
| 二号|三十五个|三十五个|三十七人|
| 二号|三十五个|三十五个|三十七人|
| 二号|三十七人|三十五个|三十七人|
| 二号|三十八|三十五个|三十七人|
| C 003号|三十五个|三十五个|三十九|
| C 003号|三十九|三十五个|三十九|
| C 004色|三十六人|三十六人|三十七人|
| C 004色|三十七人|三十六人|三十七人|
而对于最后的结果会这样显示:
| 客户ID|第一个|第二个|
| - -|- -|- -|
| 第001号|三十五个|三十七人|
| 二号|三十五个|三十七人|
| C 003号|三十五个|三十九|
C 004不包括在内,因为我需要谁的客户ID谁在他们的第一周先来。

xfyts7mz

xfyts7mz1#

您可以在子查询中使用ROW_NUMBER()函数来获取客户的第一个和第二个交易日期,然后对该子查询的结果使用条件MAX窗口函数。

SELECT CustomerID, DATEPART(week,CustTrans) AS Trans_week,
       DATEPART(week, MAX(CASE rn WHEN 1 THEN CustTrans END) OVER (PARTITION BY CustomerID)) first,
       DATEPART(week, MAX(CASE rn WHEN 2 THEN CustTrans END) OVER (PARTITION BY CustomerID)) second
FROM
  (
    SELECT *,
      ROW_NUMBER() OVER (PARTITION BY CustomerID ORDER BY CustTrans) rn
    FROM trydata
  ) T
ORDER BY CustomerID, Trans_week

请参阅SQL Server上的demo
根据您在注解中的请求,如果您希望为每个客户仅选择一行来显示第一周和第二周,请使用以下查询:

SELECT CustomerID,
   DATEPART(week, MAX(CASE rn WHEN 1 THEN CustTrans END)) first,
   DATEPART(week, MAX(CASE rn WHEN 2 THEN CustTrans END)) second
FROM
  (
    SELECT *,
      ROW_NUMBER() OVER (PARTITION BY CustomerID ORDER BY CustTrans) rn
    FROM trydata
  ) T
WHERE rn <= 2
GROUP BY CustomerID
ORDER BY CustomerID

请参见demo

vuktfyat

vuktfyat2#

with cte (RN,CustomerID, FirstWeek,SecondWeek ) as
( SELECT ROW_NUMBER() over(partition by CustomerID  ORDER BY CustomerID  )  RN, CustomerID,FirstWeek, isnull((select TOP 1 (DATEPART(week,CustTrans))   
                from trydata c 
                    where c.CustomerID = SRC.CustomerID AND DATEPART(week,C.CustTrans) > SRC.FirstWeek  
                    ORDER BY DATEPART(week,C.CustTrans) ),'0')  AS SecondWeek 
FROM (  
    SELECT CustomerID,DATEPART(week,CustTrans) TransWeek,
      (select MIN(DATEPART(week,CustTrans)) from trydata c where c.CustomerID = trydata.CustomerID) AS FirstWeek
    FROM trydata
) SRC )

select CustomerID,FirstWeek,SecondWeek from cte where RN = 1

输出量:
例二:

WITH CTE (CustomerID,FIrstWeek,RN) AS (
    SELECT CustomerID,MIN(DATEPART(week,CustTrans)) TransWeek,
    ROW_NUMBER() over(partition by CustomerID  ORDER BY DATEPART(week,CustTrans) asc ) FROM TryData 
    GROUP BY CustomerID,DATEPART(week,CustTrans)
) 

SELECT CTE.CustomerID, CTE.FIrstWeek,  
     (select TOP 1 (DATEPART(week,c.CustTrans))   
        from trydata c 
            where c.CustomerID = CTE.CustomerID AND DATEPART(week,C.CustTrans) > CTE.FIrstWeek 
                )   SecondWeek 
FROM CTE  
WHERE RN = 1

FIddle Demo
编辑:这可以用更简单的方法和更简单的方法来完成。

相关问题