我有一个看起来像这样的数据表。
|Key|LotId|TransactionType|Quantity|Destination
|1 |A |Transform |NULL |Foo
|2 |A |Transform |NULL |Bar
|3 |A |Consume |100 |NULL
|4 |B |Transform |NULL |Bob
|5 |B |Transform |NULL |Fred
|6 |B |Consume |75 |NULL
|7 |B |Consume |50 |NULL
|8 |B |Transform |NULL |Sally
|9 |B |Transform |NULL |Fred
|10 |B |Consume |60 |NULL
|11 |C |Transform |NULL |Bar
|12 |C |Transform |NULL |Fred
|13 |C |Consume |25 |NULL
转换线告诉我我的数量去了哪里,消耗线告诉我使用了多少数量。消费行适用于该 LotId 的所有先前转换行,直到前一个 LotId 或如果它与前一个转换和消费分组相同的 LotId。并且增加一个 Spanner ,一组内的变换和消耗线的数量是可变的。我确实为我工作的一件事是变换线先出现,然后消耗,下次我遇到变换时,我知道新的分组已经开始。
|Key|LotId|TransactionType|Quantity|Destination|Grouping
|1 |A |Transform |NULL |Foo |A1
|2 |A |Transform |NULL |Bar |A1
|3 |A |Consume |100 |NULL |A1
---------------------------------------------------------
|4 |B |Transform |NULL |Bob |B1
|5 |B |Transform |NULL |Fred |B1
|6 |B |Consume |75 |NULL |B1
|7 |B |Consume |50 |NULL |B1
---------------------------------------------------------
|8 |B |Transform |NULL |Sally |B2
|9 |B |Transform |NULL |Fred |B2
|10 |B |Consume |60 |NULL |B2
---------------------------------------------------------
|11 |C |Transform |NULL |Bar |C1
|12 |C |Transform |NULL |Fred |C1
|13 |C |Consume |25 |NULL |C1
(出于本示例的目的,我们将假设数量在所有各方之间平均分配)
使用 sql
RANK()
, DENSE_RANK()
, & ROW_NUMBER()
窗口 我正在尝试解决一个查询,它将给我这个分组。一旦我能够得到这个分组,我就应该能够将数据连接回自身并最终确定我的每个目的地收到了多少。这是在 SQL2008 上。
最佳答案
使用 common table expression 的组合, outer apply()
, 和 dense_rank()
注意:我更改了列Key
至 tKey
所以我不必在它周围使用方括号。
;with cte as (
select *
, PrevTransactionType=isnull(x.Prev_TransactionType,'Consume')
from t
outer apply (
select top 1
Prev_TransactionType = TransactionType
from t as i
where i.tKey < t.tKey
order by i.tKey desc
) as x
)
select t.tKey, t.LotId, t.TransactionType, t.Quantity, t.Destination
, Grouping = LotId + convert(varchar(10),dense_rank() over (
partition by LotId
order by GroupNumber
)
)
from cte as t
outer apply (
select top 1
GroupNumber = i.tKey
from cte as i
where i.tKey <= t.tKey
and i.TransactionType = 'Transform'
and i.PrevTransactionType = 'Consume'
order by i.tKey desc
) x
测试设置:http://rextester.com/LWV40248
结果:
+------+-------+-----------------+----------+-------------+----------+
| tKey | LotId | TransactionType | Quantity | Destination | Grouping |
+------+-------+-----------------+----------+-------------+----------+
| 1 | A | Transform | NULL | Foo | A1 |
| 2 | A | Transform | NULL | Bar | A1 |
| 3 | A | Consume | 100 | NULL | A1 |
| 4 | B | Transform | NULL | Bob | B1 |
| 5 | B | Transform | NULL | Fred | B1 |
| 6 | B | Consume | 75 | NULL | B1 |
| 7 | B | Consume | 50 | NULL | B1 |
| 8 | B | Transform | NULL | Sally | B2 |
| 9 | B | Transform | NULL | Fred | B2 |
| 10 | B | Consume | 60 | NULL | B2 |
| 11 | C | Transform | NULL | Bar | C1 |
| 12 | C | Transform | NULL | Fred | C1 |
| 13 | C | Consume | 25 | NULL | C1 |
+------+-------+-----------------+----------+-------------+----------+
关于sql-server - SQL 分区通过交替的行组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42426353/