很难用短语表达这个标题。
我有一个数据表,其中每个发票都包含一行。例如:
| Invoice ID | Customer Key | Date | Value | Something |
| ---------- | ------------ | ---------- | ------| --------- |
| 1 | A | 08/02/2019 | 100 | 1 |
| 2 | B | 07/02/2019 | 14 | 0 |
| 3 | A | 06/02/2019 | 234 | 1 |
| 4 | A | 05/02/2019 | 74 | 1 |
| 5 | B | 04/02/2019 | 11 | 1 |
| 6 | A | 03/02/2019 | 12 | 0 |
我需要添加另一列,该列计算每个CustomerKey先前的行数,但仅当“ Something”等于1时,以便它返回以下内容:
| Invoice ID | Customer Key | Date | Value | Something | Count |
| ---------- | ------------ | ---------- | ------| --------- | ----- |
| 1 | A | 08/02/2019 | 100 | 1 | 2 |
| 2 | B | 07/02/2019 | 14 | 0 | 1 |
| 3 | A | 06/02/2019 | 234 | 1 | 1 |
| 4 | A | 05/02/2019 | 74 | 1 | 0 |
| 5 | B | 04/02/2019 | 11 | 1 | 0 |
| 6 | A | 03/02/2019 | 12 | 0 | 0 |
我知道我可以使用这样的CTE来做到这一点...
(
select
count(*)
from table
where
[Customer Key] = t.[Customer Key]
and [Date] < t.[Date]
and Something = 1
)
但是我有很多数据,而且速度很慢。我知道我也可以使用交叉应用来实现相同的目的,但是据我所知,这并不比仅使用CTE更好。
所以;有没有更有效的方法来实现这一目标,或者我只是把它吸了呢?
编辑:我最初发布此内容时不需要所有Something = 1
所在的行。 Mea culpa-我急着问。不幸的是,我认为这意味着我不能使用row_number() over (partition by [Customer Key])
答案 0 :(得分:5)
如果您不使用2012,则可以使用ROW_NUMBER
ROW_NUMBER() OVER (PARTITION BY CustomerKey ORDER BY [Date]) - 1 AS Count
答案 1 :(得分:4)
假设,您正在使用SQL Server 2012+,则可以使用“窗口函数”:
COUNT(CASE WHEN Something = 1 THEN CustomerKey END) OVER (PARTITION BY CustomerKey ORDER BY [Date]
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) -1 AS [Count]
在需要新逻辑之前的旧答案:
COUNT(CustomerKey) OVER (PARTITION BY CustomerKey ORDER BY [Date]
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) -1 AS [Count]