Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
Author |
Topic |
smh
Yak Posting Veteran
94 Posts |
Posted - 2012-05-04 : 23:07:34
|
Hi All: In a table we have 9 columns in each rowLet us call these columns Level1, Level2, …Level9There are numerical values (decimal) in each of these columns.Some values may be 0.The values are in descending order. Thus Level1>=Level2 >=Level3 etc.For a numerical integer parameter, P, that may have a value from 1 to 9, we must obtain for each row in the table the first non-zero value in columns named Level P or less, traversing the columns in descending sequence of column nameFor example, if P=5, and the values in Row17 are Level1 3.85 Level2 3.80 Level3 0 Level4 0 Level5 0 Level6 0 Level7 2.65 Level8 0 Level9 2.25Then the function should return 3.80And if P=5 and the values in Row 18 are Level1 3.65 Level2 3.60 Level3 0 Level4 0 Level5 3.40 Level6 0 Level7 2.45 Level8 2.35 Level9 0Then the function should return 3.40If all values are 0, the function should return 0The value P will be the same for each row (here it is 5)I have just been going thru each column with an "if" statement to see if the level is <= value P and then capturing the decimal value (if greater than 0) in a variable. I have to check each level up to level 9 even if P is < 9 because I am not "looping" thru the columns and don't know if that is possible.Any help appreciated.Thanks Everyone. |
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-05-05 : 01:05:18
|
i think best way to do is to first apply unpivot and then do the searxhlike;With CTEAS(SELECT ROW_NUMBER() OVER(PARTITION BY RowID ORDER BY Col DESC) AS Rn,Val,Col,RowIDFROM table tUNPIVOT(Val FOR Col IN ([Col1],[Col2],...[Col9]))u)SELECT RowID,COALESCE(Val,0)FROM (SELECT DISTINCT RowID FROM CTE)cOUTER APPLY (SELECT Top 1 Val FROM CTE WHERE Val >0 AND RowID = c.RowID ORDER BY Rn)c1 ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
RL
Starting Member
15 Posts |
Posted - 2012-05-05 : 14:11:37
|
Nice UNPIVOT example. I used an old-school subquery (still learning {CROSS|OUTER APPLY}). Lower optimizer cost because it doesn't need the ROW_NUMBER() column in CTE. Still defaults to zero using COALESCE.Below is code for a scalar function (returns a single value) with params @row_id and @col_name. Syntax: SELECT dbo.fn_get_value(@row_id, @col_name)NOTE: Avoid using scalar functions in WHERE or JOIN, use inline function (returns result set) instead for better performance.CREATE FUNCTION dbo.fn_get_value( @row_id INT, @col_name VARCHAR(50))RETURNS DEC(5,2)ASBEGIN DECLARE @value DEC(5,2); With CTE AS ( SELECT RowID, Col, Val FROM table UNPIVOT(Val FOR Col IN (Col1, Col2, Col3, Col4, Col5, Col6, Col7, Col8, Col9)) u ) SELECT @value = Val FROM CTE C1 WHERE RowID = @row_id AND Col = COALESCE((SELECT MAX(Col) FROM CTE WHERE Val > 0. AND RowID = C1.RowID AND Col <= @col_name), 'Col1'); RETURN (@value);ENDGO |
 |
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-05-05 : 14:17:02
|
actually you dont need rownumber if col values are alphabetical. I just added it for extra safetyeven this would suffice;With CTEAS(SELECT Val,Col,RowIDFROM table tUNPIVOT(Val FOR Col IN ([Col1],[Col2],...[Col9]))u)SELECT RowID,COALESCE(Val,0)FROM (SELECT DISTINCT RowID FROM CTE)cOUTER APPLY (SELECT Top 1 Val FROM CTE WHERE Val >0 AND RowID = c.RowID ORDER BY Col DESC)c1 ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
RL
Starting Member
15 Posts |
Posted - 2012-05-05 : 18:46:18
|
Using TOP 1, I agree it's best to sort rather than assume they are naturally in order. But it turns out the ROWNUM column in CTE is not the main cause of the extra optimizer cost after all. Most of it is from ORDER BY, which isn't necessary with MAX(Col). (Not that I knew that when I wrote it! :) ) |
 |
|
smh
Yak Posting Veteran
94 Posts |
Posted - 2012-05-06 : 01:19:41
|
Hi everyone.I am looking at all of these, trying to understand, and will soon try them out on my work problem at the beginning of the week. I thank you all. This is very complicated for me, even though simply and elegantly put in the code examples. I have never used the coalsce or the pivot, unpivot, or rownumber() partitian. In this case I am using 9 if statements in the select statment on each row so I hope to your examples lead to a better way. By the way , the field names in my case are price1, price2, price3...price9 |
 |
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-05-06 : 13:26:10
|
quote: Originally posted by smh Hi everyone.I am looking at all of these, trying to understand, and will soon try them out on my work problem at the beginning of the week. I thank you all. This is very complicated for me, even though simply and elegantly put in the code examples. I have never used the coalsce or the pivot, unpivot, or rownumber() partitian. In this case I am using 9 if statements in the select statment on each row so I hope to your examples lead to a better way. By the way , the field names in my case are price1, price2, price3...price9
understand them herehttp://www.codeproject.com/Articles/193842/Working-with-Pivot-and-UnPivot-Transformationhttp://www.databasejournal.com/features/mssql/article.php/3572301/RowNumber-function-in-SQL-Server-2005.htm------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
|
|
|
|