如何为 SQL 中的每个帐户 ID 从第一行中减去下一行?

How to subtract next row from first one for each account id in SQL?

我要回答的问题是如何 return 每个 ID 的正确顺序和星期顺序?例如,虽然每个 ID 的第一周确实总是从 1 开始(它是系列中的第一周),但系列中的下一个日期也可能在第一周内(例如,return 1)或者可能是第 3 周的日期(例如,return 3 也应该如此)。

到目前为止我写的代码是:

select distinct 
row_number() over (partition by ID group by date) row_nums
,ID
,date 
from table_a

这只是 return运行 按 ID 计算的日期总数,并没有考虑该日期所在的周数。

但我要找的是这个:

这里有一些设置代码可以提供帮助:

CREATE TABLE random_table

  (
  ID VarChar(50),
date DATETIME
 );

 INSERT INTO random_table
 VALUES
  ('AAA',5/14/2021),
('AAA',6/2/2021),
('AAA',7/9/2021),
('BBB', 5/25/2021),
('CCC', 12/2/2020),
('CCC',12/6/2020),
('CCC',12/10/2020),
('CCC',12/14/2020),
('CCC',12/18/2020),
('CCC',12/22/2020),
('CCC',12/26/2020),
('CCC',12/30/2020),
('CCC',1/3/2021),
('DDD',1/7/2021),
('DDD',1/11/2021)

您的 objective 不清楚,但我认为您会受益于 Tally-Table 周然后 LEFT JOIN 到您的源数据。 这将为您提供每周一行和源数据(如果存在)

with adj as (
    select *, dateadd(day, -1, "date") as adj_dt
    from table_a
)
select
    datediff(week,
        min(adj_dt) over (partition by id),
        adj_dt) + 1 as week_logic,
    id, "date"
from adj

这假设您对周的想法与 @@datefirst 设置为星期日相对应。对于星期日到星期六的定义,您会在同一周内找到 12/06/2020 和 12/10/2020,因此大概您想要类似星期一的开始(这似乎也与 12/02/ 的编号一致) 2020、12/14/2020 和 12/18/2020。)我通过在周计算中向后滑动一天来进行补偿。该步骤可以在没有 CTE 的情况下在线处理,但也许它更清楚地说明了该方法。

SELECT  
   CASE WHEN ROW_NUMBER() OVER (PARTITION BY ID ORDER BY [date])=1 THEN 1 
        ELSE DATEPART(WK, (DATE) ) - DATEPART(WK, FIRST_VALUE([DATE]) OVER (PARTITION BY ID ORDER BY [date])) END  PD,
   ID,
   CONVERT(VARCHAR(10), [date],120)
FROM random_table rt 
ORDER BY ID,[date]

DBFIDDLE

输出:

PD ID (No column name)
1 AAA 2021-05-14
3 AAA 2021-06-02
8 AAA 2021-07-09
1 BBB 2021-05-25
1 CCC 2020-12-02
1 CCC 2020-12-06
1 CCC 2020-12-10
2 CCC 2020-12-14
2 CCC 2020-12-18
3 CCC 2020-12-22
3 CCC 2020-12-26
4 CCC 2020-12-30
-47 CCC 2021-01-03
1 DDD 2021-01-07
1 DDD 2021-01-11
  • 日期格式为 YYYY-MM-DD
  • 我会把-47留在这里,所以你可以自己修复它(作为练习)