简体   繁体   中英

sql server - for loop - cross apply

For the table below, I need to perform a loop operation in SQL Server 2008:

The column Day in the table can have values from 0 to 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;

Table A:

Key|Day| x  | y |
---|---|----|---|
123| 0 |7000|   |
123| 2 |6000|   |
123| 9 |6500|   |

I have used cross apply and got the following:

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

Output:

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 

Not able to figure out how to get y=y+1 for every k.

I am not allowed to use join . But if the performance of join is better than cross apply, please do share the solution.

Please help. Thanks

Edit: I tried the following to calculate running totals with the condition:

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

But it doesn't give me the correct output. I get:

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 

Also, when I use order by in the over clause it gives me an error:

The Parallel Data Warehouse (PDW) features are not enabled.

You're very close. I'm running SQL Server 2016. The result should be the same. Note Key and Day column in your expected result don't match original data in TableA.

WITH TableY AS
(
    SELECT A.[Key], A.[Day], A.X AS xj, B.[Day] AS k, B.X AS xk, 
    (CASE WHEN B.X >= A.X THEN 1 ELSE 0 END) AS y
    FROM @TableA AS A
    INNER JOIN @TableA AS B ON A.[Key] = B.[Key]
)
SELECT *,
    SUM(y) OVER(
         PARTITION BY [Key], [Day] 
         ORDER BY k 
         ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
    ) AS 'RunningTotalY'
FROM TableY
ORDER BY [Key], [Day], xj, k;

Not sure how PDW error came from.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM