【发布时间】:2016-09-30 14:25:10
【问题描述】:
对于下表,我需要在 SQL Server 2008 中执行循环操作:
表中Day列的值可以是0到9。
For j = 0 to 9: (Iterate through the column **Day**)
y=0;
For k = 0 to 9: (Iterate through the column **Day** again)
if x[k] >= x[j]: y= y+1;
表 A:
Key|Day| x | y |
---|---|----|---|
123| 0 |7000| |
123| 2 |6000| |
123| 9 |6500| |
我使用过交叉申请并得到以下结果:
select * from TableA A
cross apply (
select Day as k, case when B.x >= A.x then 1 else 0 end as y
from TableA B
where A.Key = B.Key
) C
输出:
Key|Day|x[j]|k |x[k]|y |y - What I need
---|---|----|--|----|--|----------------
123|0 |7000|0 |7000|1 |1
123|0 |7000|2 |6000|0 |1
123|0 |7000|9 |6500|0 |1
123|2 |6000|0 |7000|1 |1
123|2 |6000|2 |6000|1 |2
123|2 |6000|9 |6500|1 |3
123|9 |6500|0 |7000|1 |1
123|9 |6500|2 |6000|0 |1
123|9 |6500|9 |6500|1 |2
无法弄清楚如何为每个 k 获得 y=y+1。
我不允许使用join。但是如果join的性能优于cross apply,请分享解决方案。
请帮忙。谢谢
编辑: 我尝试了以下方法来计算符合条件的运行总数:
select * from TableA A
cross apply (
select Day as k
,sum(case when B.x >= A.x then 1 else 0 end) over (partition by A.Key,A.Day) as y
from TableA B
where A.Key = B.Key
) C
但它没有给我正确的输出。我明白了:
Key|Day|x[j]|k |x[k]|y |y - What I need
---|---|----|--|----|--|----------------
123|0 |7000|0 |7000|1 |1
123|0 |7000|2 |6000|1 |1
123|0 |7000|9 |6500|1 |1
123|2 |6000|0 |7000|3 |1
123|2 |6000|2 |6000|3 |2
123|2 |6000|9 |6500|3 |3
123|9 |6500|0 |7000|2 |1
123|9 |6500|2 |6000|2 |1
123|9 |6500|9 |6500|2 |2
另外,当我在 over 子句中使用 order by 时,它会给我一个错误:
The Parallel Data Warehouse (PDW) features are not enabled.
【问题讨论】:
-
为什么“不允许”使用
join?cross apply也是一个“连接”——横向交叉连接。 -
遗憾的是,我对此没有明确的答案。数据库每分钟处理大量事务。但是我必须执行上述操作的表每天只更新一次,所以如果使用
join的解决方案性能更好,我会尝试说服我的“上级”。 -
您在交叉连接方面做得对,但您遇到了总计(最后一列)。尝试搜索它。
-
您需要一个运行总计(有条件)。 SQL Server 2012+ 可以有效地做到这一点。在 2008 年,使用游标可能更有效。或者在客户端计算运行总和。
-
您的最新查询确实给出了正确的最后一列。你还想要什么?
标签: sql sql-server sql-server-2008