| Author |
Topic |
|
kotonikak
Yak Posting Veteran
92 Posts |
Posted - 2012-06-04 : 16:03:03
|
| I have the following data:LAmount seq IIntegral6087 1 696402605 2 29702308 3 2002278 4 25401770 5 28401060 6 1153.333333714 7 10722.85714-3039 8 2287.5-3954 9 6668.888889-6955 10 1134-7522 11 2027.272727-8637 12 713.3333333-9065 13 3872.307692-11582 14 2524.285714-13349 15 1373.333333-14379 16 3933.75-17526 17 240-17730 18 3726.666667-21084 19 2684.210526and want the following column:Integral48441.73936 (Sum of IIntegral from seq 4 - seq 19)48441.73936 (Sum of IIntegral from seq 4 - seq 19)48441.73936 (Sum of IIntegral from seq 4 - seq 19)48441.73936 (Sum of IIntegral from seq 4 - seq 19)45901.73936 (Sum of IIntegral from seq 5 - seq 19)43061.73936 (Sum of IIntegral from seq 6 - seq 19)41908.40603 (Sum of IIntegral from seq 7 - seq 19)31185.54888 so on...28898.0488822229.1599921095.1599919067.8872718354.5539314482.2462411957.9605310584.627196650.8771936410.8771932684.210526Basically, I want it to recognize that if the sequence is greater than or equal to 4, to do the summation of IIntegral from that sequence all the way to the last sequence, and if it is less than 4, to only do the sum of sequence 4 to 19 (it's supposed to be 20 but i have to fix the code...this shouldn't affect anything for this question)First, I have the following cte to recognize the 4th sequence (or any sequence depending on the number of rows and the percentile)...right now @row = 20 and @VaR=80.00with d as ( select LAmount, seq = row_number() over (order by LAmount desc) from dbo.Data2 ) ,VaRVariable as ( select LAmount from d where seq = @row-(@row*(@VaR/100)) ) select * from VaRVariable I also have an older code which actually did the summation of IIntegral starting at sequence 1-19, sequence 2-19, sequence 3-19 and so on...but now depending on the sequence I get from the formula above, I want it to get the column I mentioned above. Here is the older code (part of the cte above):,temp4 as ( select sum(b.IIntegral) as Integral from temp3 a CROSS JOIN temp3 b where a.seq<=b.seq group by a.seq )which yielded the following column:Integral121251.739451611.7393648641.7393648441.7393645901.7393643061.7393641908.4060331185.5488828898.0488822229.1599921095.1599919067.8872718354.5539314482.2462411957.9605310584.627196650.8771936410.8771932684.210526Do I have to use an if statement to do what I want or is there an easier way to approach this? Any help would be greatly appreciated! (Sorry if what I'm asking is confusing) |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-06-04 : 16:27:09
|
| [code]SELECT t.*,t1.AccSumFROM table tCROSS APPLY (SELECT SUM(IIntegral) AS AccSum FROM table WHERE (seq >= t.Seq OR seq <=4) AND seq <=19 )t1[/code]------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
vinu.vijayan
Posting Yak Master
227 Posts |
Posted - 2012-06-05 : 03:26:53
|
quote: Originally posted by visakh16
SELECT t.*,t1.AccSumFROM table tCROSS APPLY (SELECT SUM(IIntegral) AS AccSum FROM table WHERE (seq >= t.Seq OR seq <=4) AND seq <=19 )t1 Nice one Visakh.Very compact.------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/
N 28° 33' 11.93148"E 77° 14' 33.66384" |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-06-05 : 10:23:26
|
| Thanks------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
kotonikak
Yak Posting Veteran
92 Posts |
Posted - 2012-06-05 : 12:01:28
|
| I tried your code and it didn't work properly. I got the following columns:seq AccSum19 78034.2105318 81760.8771917 82000.8771916 85934.6271915 87307.9605314 89832.2462413 93704.5539312 94417.8872711 96445.1599910 97579.159999 104248.04898 106535.54897 117258.4066 118411.73945 121251.73944 121251.73943 121251.73942 121251.73941 121251.7394However, I did update my old code to the following and produced closer results to what I want: select min(a.seq) as seq, sum(b.IIntegral) as AccSum from temp3 a CROSS JOIN temp3 b where (a.seq<=b.seq or a.seq<=(4-1) and a.seq<=19) group by a.seqand this gave me the following results:seq AccSum1 121251.7392 121251.7393 121251.7394 48441.739365 45901.739366 43061.739367 41908.406038 31185.548889 28898.0488810 22229.1599911 21095.1599912 19067.8872713 18354.5539314 14482.2462415 11957.9605316 10584.6271917 6650.87719318 6410.87719319 2684.210526which is very close to what I want...the only thing is that the first 3 rows (seq 1-3) are adding the IIntegral values from seq 1-19 instead of seq 4-19...so now i'm stuck..Is there any way to update your old code or mine to make this work properly? I've been looking at it and changing things around for a couple hours and don't know what to do.... |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-06-05 : 12:29:12
|
what about this?SELECT t.*,t1.AccSumFROM table tCROSS APPLY (SELECT SUM(IIntegral) AS AccSum FROM table WHERE seq >= CASE WHEN t.Seq < 4 THEN 4 ELSE t.Seq END AND seq <=19 )t1 ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
kotonikak
Yak Posting Veteran
92 Posts |
Posted - 2012-06-05 : 14:20:58
|
| that did the job. thank you! |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-06-05 : 14:43:06
|
| wc------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
kotonikak
Yak Posting Veteran
92 Posts |
Posted - 2012-06-15 : 12:11:29
|
| Is there any way to do this problem without using CROSS APPLY? It works perfectly it's just that I have a database with hundreds of thousands of rows and CROSS APPLY just takes A LOT of time... |
 |
|
|
robvolk
Most Valuable Yak
15732 Posts |
Posted - 2012-06-15 : 14:02:15
|
Here's a variation on my earlier reply that doesn't use CROSS APPLY:SELECT a.seq, SUM(CASE WHEN b.seq>=4 THEN b.IIntegral END) integralFROM table a CROSS JOIN @table b WHERE a.seq<=b.seqGROUP BY a.seqORDER BY a.seq DESC The plan is very similar to visakh's query, possibly worse but needs testing. Of course if you could upgrade to SQL 2012:SELECT *, SUM(CASE WHEN seq>=4 THEN IIntegral END) OVER (ORDER BY Seq DESC) FROM table This is a significantly better plan, it has no loops or joins. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-06-15 : 15:43:08
|
quote: Originally posted by robvolk Here's a variation on my earlier reply that doesn't use CROSS APPLY:SELECT a.seq, SUM(CASE WHEN b.seq>=4 THEN b.IIntegral END) integralFROM table a CROSS JOIN @table b WHERE a.seq<=b.seqGROUP BY a.seqORDER BY a.seq DESC The plan is very similar to visakh's query, possibly worse but needs testing. Of course if you could upgrade to SQL 2012:SELECT *, SUM(CASE WHEN seq>=4 THEN IIntegral END) OVER (ORDER BY Seq DESC) FROM table This is a significantly better plan, it has no loops or joins.
why?wont it work in sql 2005/2008? I think it should work from 2005 onwards------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
robvolk
Most Valuable Yak
15732 Posts |
Posted - 2012-06-15 : 15:54:43
|
| Nope, ORDER BY in the OVER clause is not supported in aggregate functions prior to 2012. You get a syntax error. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-06-15 : 15:57:05
|
quote: Originally posted by robvolk Nope, ORDER BY in the OVER clause is not supported in aggregate functions prior to 2012. You get a syntax error.
oh okI missed that partThought its PARTITION BYsorry about that ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
kotonikak
Yak Posting Veteran
92 Posts |
Posted - 2012-06-18 : 15:23:01
|
| This problem is working just fine if I have the simple data above but I seem to be running into issues with this problem when i change the data around. In my previous example, I only had one sequence pertaining to one IIntegral value and that's it. I am now expanding my data to include these numbers (sample numbers):seq RowID ColID IIntegral1 01 A 51 02 B 51 03 C 52 01 A 92 02 B 92 03 C 93 01 A 83 02 B 83 03 C 8Because I have a different RowID and ColID at a specific sequence number, when I take the integral (from the code using CROSS APPLY) I get the following column (If i'm summing everything up and not up to a certain point):Integral666666 (5+5+5+9+9+9+8+8+8)515151 (9+9+9+8+8+8)242424 (8+8+8)Basically, it's taking the sum of the IIntegral at that sequence number and adding all those together and so on....that's not what I want.I want:Integral:222222 (5+9+8)1717 17 (9+8)888 (8)Is there any way for sql to recognize that I only want that one IIntegral number to add up and not all the values at that specific sequence number?sorry again if this is confusing... |
 |
|
|
robvolk
Most Valuable Yak
15732 Posts |
Posted - 2012-06-18 : 15:45:34
|
| [code]DECLARE @table TABLE(seq INT, RowID CHAR(2), ColID CHAR(1), IIntegral FLOAT)INSERT @table SELECT1,'01','A',5 UNION ALL SELECT 1,'02','B',5 UNION ALL SELECT 1,'03','C',5 UNION ALL SELECT 2,'01','A',9 UNION ALL SELECT 2,'02','B',9 UNION ALL SELECT 2,'03','C',9 UNION ALL SELECT 3,'01','A',8 UNION ALL SELECT 3,'02','B',8 UNION ALL SELECT 3,'03','C',8SELECT t.*,t1.AccSumFROM @table tCROSS APPLY (SELECT SUM(IIntegral) AS AccSum FROM @table WHERE ColID=t.ColID AND RowID=t.RowID AND seq >= t.Seq )t1[/code] |
 |
|
|
kotonikak
Yak Posting Veteran
92 Posts |
Posted - 2012-06-19 : 09:50:49
|
| I did try to do something like that earlier but it was taking forever to execute....my data right now has 10,200 rows and new data will have about 5,100,000 rows...I am trying to execute the method and it's been 13 minutes and still hasn't finished. Is there ANY possible way to not use any cross apply or cross joins? |
 |
|
|
DonAtWork
Master Smack Fu Yak Hacker
2167 Posts |
Posted - 2012-06-19 : 09:54:05
|
| 10,000 rows should not take that long. I would suggest checking for missing indexes.How to ask: http://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspx |
 |
|
|
robvolk
Most Valuable Yak
15732 Posts |
Posted - 2012-06-19 : 10:03:28
|
You can try a cursor.       Or upgrade to SQL Server 2012.There is a quirky behavior with the UPDATE statement that you might be able to use:http://www.sqlteam.com/article/creating-a-sequential-record-number-fieldhttp://consultingblogs.emc.com/jamiethomson/archive/2006/02/28/3001.aspxThe problem is it's not standard or consistent behavior. I've used it several times when left with no choice, but it requires clustering the data a certain way and even then it's not guaranteed to work correctly. (I always use a temp table, not a table variable, so I can force a clustered index on it)Another option is a CLR function:http://sqlblog.com/blogs/adam_machanic/archive/2006/07/12/running-sums-yet-again-sqlclr-saves-the-day.aspxDare I suggest (again) that SQL Server is not really the best tool for this kind of thing? It's not a general purpose programming language. This is a running total and most properly resides in a reporting layer that is designed to do such things. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-06-19 : 14:12:48
|
quote: Originally posted by kotonikak I did try to do something like that earlier but it was taking forever to execute....my data right now has 10,200 rows and new data will have about 5,100,000 rows...I am trying to execute the method and it's been 13 minutes and still hasn't finished. Is there ANY possible way to not use any cross apply or cross joins?
check execution plan and identify costly steps------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
|