IFS and INDEX/ MATCH EXCEL COUNTERPART IN SQL QUERY - sql

My table looks like this
NAME BRAND REFERENCE COMMENTS <-Expected output
-------------------------------------------------
Gu Skirt 101128 Pants
Cci Pants 101127 Pants
Cha Skirt paired paired
Gu Pants 101128 Skirts
Nel Skirt nonpaired UNIQUE
Gir Pants 101188 Skirt
Baud Skirt dropped DROPPED
Le Pants paired PAIRED
Gir Skirt 101188 101178
Vis Socks blanks
Cci Skirts 101127 Skirts
I wonder what code to use to get the Comments result.
First reference in NUMBERS should be paired. If reference numbers match, return value should be the Brand counterpart.
If reference is in Character, they have to fall under if statements: IF character is Nonpaired return value should be unique, dropped for dropped and so on. If the reference is blanks no change.
Is this possible?
Thank you so much.

You can use common table expressions to break down the problem which can help with maintaining the code.
I didn't use lag/lead because you only have two rows in the pair, so numbering the rows and joining the table to itself felt quicker and easier to follow.
Here's the code I've used to answer and test your question;
create table #source
(
[NAME] varchar(200),
[BRAND] varchar(200),
[REFERENCE] varchar(200)
);
insert into #source values
('Gu','Skirt','101128'),
('Cci','Pants','101127'),
('Cha','Skirt','paired'),
('Gu','Pants','101128'),
('Nel','Skirt','nonpaired'),
('Gir','Pants','101188'),
('Baud','Skirt','dropped'),
('Le','Pants','paired'),
('Gir','Skirt','101188'),
('Vis','Socks',''),
('Cci','Skirts','101127'),
('Le','Socks','101188'),
('Uno','Socks','101101');
select * from #source;
with cteNumericRef as
(
select [NAME],[BRAND],[REFERENCE]
from #source
where ISNUMERIC([REFERENCE]) = 1
)
, cteCheckRow as
(
select [REFERENCE],
'CHECK' as [COMMENT]
from cteNumericRef
group by [REFERENCE]
having count(*) <> 2
)
, ctePairedRow as
(
select
num_ref.[NAME]
, num_ref.[BRAND]
, num_ref.[REFERENCE]
, row_number() over (partition by num_ref.[REFERENCE] order by num_ref.[NAME]) as [Pair_Num]
from cteNumericRef num_ref
left join cteCheckRow check_row
on check_row.[REFERENCE] = num_ref.[REFERENCE]
where check_row.[REFERENCE] is null
)
, cteTextRow as
(
select [NAME],[BRAND],[REFERENCE],
case [REFERENCE]
when 'paired' then 'PAIRED'
when 'nonpaired' then 'UNIQUE'
when 'dropped' then 'DROPPED'
when '' then ''
else 'CHECK' end as [COMMENT]
from #source
where ISNUMERIC([REFERENCE]) <> 1
)
select
left_row.[NAME]
, left_row.[BRAND]
, left_row.[REFERENCE]
, right_row.[BRAND] as [COMMENTS]
from ctePairedRow left_row
inner join ctePairedRow right_row
on left_row.[REFERENCE] = right_row.[REFERENCE]
and left_row.[Pair_Num] <> right_row.[Pair_Num]
union all
select
num_ref.[NAME]
, num_ref.[BRAND]
, num_ref.[REFERENCE]
, check_row.[COMMENT]
from cteNumericRef num_ref
inner join cteCheckRow check_row
on check_row.[REFERENCE] = num_ref.[REFERENCE]
union all
select
[NAME]
, [BRAND]
, [REFERENCE]
, [COMMENT]
from cteTextRow;
drop table #source

SELECT Name,
Brand,
Reference,
CASE WHEN Reference = 'Paired' THEN 'Paired'
WHEN Reference = 'nonpaired' THEN 'Unique'
WHEN Reference = 'dropped' THEN 'DROPPED'
WHEN Reference = ' ' THEN 'blanks'
WHEN Reference = Next_Ref AND rownum = 1 THEN next_brand
WHEN Reference = Prev_Ref AND rownum = 2 THEN prev_brand
END AS Comments
FROM
(
SELECT Name,
Brand,
Reference,
LAG( Reference, 1 )OVER PARTITION BY ( Reference ORDER BY Brand ) AS Prev_Ref,
LEAD( Reference, 1 )OVER PARTITION BY ( Reference ORDER BY Brand ) AS Next_Ref,
LAG( Brand, 1 ) OVER PARTITION BY ( Reference ORDER BY Brand ) AS Prev_Brand,
LEAD( Brand, 1 ) OVER PARTITION BY ( Reference ORDER BY Brand ) AS Next_Brand,
ROW_NUMBER( ) OVER PARTITION BY ( Reference ORDER BY Brand ) AS rownum
FROM Data
);

Related

Use merge with certain conditions and with ROW_NUMBER function

I am trying to do a merge (insert and update) with the row_number function so that the ID_TRANS field are unique values ​​in the remaining fields apply certain conditions. But when executing it I get a right parenthesis error, it is worth mentioning that I have modified and added parentheses and it remains unresolved.
MERGE INTO TBL_TRANSAC trans
USING (
SELECT ID_TRANS,
TIT,
BEN,
BAN,
CTA_EMI,
CTA_REC,
INST,
TYPE_TRANS,
TYPE_MOV,
CONC,
DATE_OPER,
MONT,
DIV,
ID_CONT
FROM (
SELECT T1.*
, ROW_NUMBER() OVER (PARTITION BY T1.ID_TRANS ORDER BY T1.ID_TRANS DESC)ENUMERADO
FROM (
SELECT
'speibco1_'||UPPER(REPLACE( AREA,' ',''))||
UPPER(REPLACE( FVALOR,' ',''))||
UPPER(REPLACE( CLAVE_RASTREO,' ','')) ,
TIT ,
BEN,
BAN_EM_DES,
REPLACE(UPPER(NO_TP_CTA_EMISOR),' ',''),
LTRIM(CTA_REC,'0'),
'BAN ACTINVER',
'CTA_EXTER',
'SPEI ENTRADA BCO',
CONC_2 ,
TO_DATE(TO_CHAR(FVALOR),'YYYY-MM-DD'),
REPLACE(REPLACE(IMPORTE,'-',''),' ',''),
'MXN' ,
LTRIM(CTA_REC,'0')||'0999'
FROM (SELECT *
FROM IBM_I2.I2_SPEI WHERE REPLACE(NO_TP_CTA_EMISOR,' ','') IS NOT NULL
AND ID_OPERACION='0007'
AND ESTATUS='06'
AND CTA_REC NOT IN ('70000997', '7909567'))
)
WHERE ENUMERADO=1
AND ID_TRANS IS NOT NULL
)SPEI
ON (
trans.ID_TRANS = SPEI.ID_TRANS
)
WHEN MATCHED THEN
UPDATE SET
ID_TRANS = SPEI.ID_TRANS,
TIT = SPEI.TIT ,
BEN= SPEI.BEN,
BAN=SPEI.BAN_EMISOR,
CTA_EMI=SPEI.CTA_EMI,
CTA_REC =SPEI.CTA_REC,
INST= SPEI.INST,
TYPE_TRANS=SPEI.TYPE_TRANS,
TYPE_MOV=SPEI.TYPE_MOV,
CONC=SPEI.CONC,
DATE_OPER=SPEI.DATE_OPER,
MONT=SPEI.MONT,
DIV= SPEI.DIV,
ID_CONT= SPEI.ID_CONT
WHEN NOT MATCHED THEN
INSERT (
ID_TRANS,
TIT,
BEN,
BAN,
CTA_EMI,
CTA_REC,
INST,
TYPE_TRANS,
TYPE_MOV,
CONC,
DATE_OPER,
MONT,DIV,
ID_CONT
)
VALUES
(
SPEI.ID_TRANS,
SPEI.TIT ,
SPEI.BEN,
SPEI.BAN_EMISOR,
SPEI.CTA_EMI,
SPEI.CTA_REC,
SPEI.INST,
SPEI.TYPE_TRANS,
SPEI.TYPE_MOV,
SPEI.CONC ,
SPEI.DATE_OPER,
SPEI.MONT,
SPEI.DIV ,
SPEI.ID_CONT
);
MARK ERROR THAT MISSING RIGHT PARENTESIS AFTER AND ID_TRANS IS NOT NULL
STILL PLACING THE PARENTESIS.
Looks like a closing parenthesis is missing, here:
)) --> here; should be 2, not only 1
WHERE ENUMERADO=1
AND ID_TRANS IS NOT NULL
Put parentheses and aliases to each of them, as well as the fields that are called in USING put aliases, and that worked.
FROM (SELECT *
FROM IBM_I2.I2_SPEI WHERE REPLACE(NO_TP_CTA_EMISOR,' ','') IS NOT NULL
AND ID_OPERACION='0007'
AND ESTATUS='06'
AND CTA_REC NOT IN ('70000997', '7909567')
)
)T1
)T2
WHERE ENUMERADO=1
AND ID_TRANS IS NOT NULL
)SPEI
ON (
trans.ID_TRANS = SPEI.C1_ID_TRANS
)

How to pivot multiple columns without aggregation

I use SqlServer and i have to admit that i'm not realy good with it ...
This might be and easy question for the advanced users (I hope)
I have two tables which look like this
First table (ID isn't the primary key)
ID IdCust Ref
1 300 123
1 300 124
2 302 345
And the second (ID isn't the primary key)
ID Ref Code Price
1 123 A 10
1 123 Y 15
2 124 A 14
3 345 C 18
In the second table, the column "Ref" is the foreign key of "Ref" in the first table
I'm trying to produce the following output:
[EDIT]
The column "Stock", "Code" and "Price" can have x values, so I don't know it, in advance...
I tried so many things like "PIVOT" but it didn't give me the right result, so i hope someone can solve my problem ...
Use row_number() function and do the conditional aggregation :
select id, IdCust, Ref,
max(case when Seq = 1 then stock end) as [Stock A], -- second table *id*
max(case when Seq = 1 then code end) as [Code 1],
max(case when Seq = 1 then price end) as [Price1],
max(case when Seq = 2 then stock end) as [Stock B], -- second table *id*
max(case when Seq = 2 then code end) as [Code 2],
max(case when Seq = 2 then price end) as [Price2]
from (select f.*, s.Id Stock, s.Code, s.Price,
row_number() over (partition by f.Ref order by s.id) as Seq
from first f
inner join second s on s.Ref = f.Ref
) t
group by id, IdCust, Ref;
However, this would go with known values else you would need go with dynamic solution for that.
#YogeshSharma's provided an excellent answer.
Here's the same done using Pivot; SQL Fiddle Demo.
Functionally there's no difference between the two answers. However, Yogesh's solution's simpler to understand, and performs better; so personally I'd opt for that... I included this answer only because you mention PIVOT in the question:
select ft.Id
, ft.IdCust
, ft.Ref
, x.Stock1
, x.Code1
, x.Price1
, x.Stock2
, x.Code2
, x.Price2
from FirstTable ft
left outer join (
select Ref
, max([Stock1]) Stock1
, max([Stock2]) Stock2
, max([Code1]) Code1
, max([Code2]) Code2
, max([Price1]) Price1
, max([Price2]) Price2
from
(
select Ref
, Id Stock
, Code
, Price
, ('Stock' + cast(Row_Number() over (partition by Ref order by Id, Code) as nvarchar)) StockLineNo
, ('Code' + cast(Row_Number() over (partition by Ref order by Id, Code) as nvarchar)) CodeLineNo
, ('Price' + cast(Row_Number() over (partition by Ref order by Id, Code) as nvarchar)) PriceLineNo
from SecondTable
) st
pivot (max(Stock) for StockLineNo in ([Stock1],[Stock2])) pvtStock
pivot (max(Code) for CodeLineNo in ([Code1],[Code2])) pvtCode
pivot (max(Price) for PriceLineNo in ([Price1],[Price2])) pvtPrice
Group by Ref
) x
on x.Ref = ft.Ref
order by ft.Ref
Like Yogesh's solution, this will only handle as many columns as you specify; it won't dynamically alter the number of columns to match the data. For that you'd need to do dynamic SQL. However; if you need to do that, it's more likely you're attempting to solve the problem in the wrong way... so consider your design / determine if you really need additional columns per result rather than additional rows / some alternate approach...
Here's a Dynamic SQL implementation based on #YogeshSharma's answer: DBFiddle
declare #sql nvarchar(max) = 'select id, IdCust, Ref'
select #sql = #sql + '
,max(case when Seq = 1 then stock end) as [Stock' + rowNumVarchar + ']
,max(case when Seq = 1 then code end) as [Code' + rowNumVarchar + ']
,max(case when Seq = 1 then price end) as [Price' + rowNumVarchar + ']
'
from
(
select distinct cast(row_number() over (partition by ref order by ref) as nvarchar) rowNumVarchar
from second s
) z
set #sql = #sql + '
from (select f.*, s.Id Stock, s.Code, s.Price,
row_number() over (partition by f.Ref order by s.id) as Seq
from first f
inner join second s on s.Ref = f.Ref
) t
group by id, IdCust, Ref;
'
print #sql --see what the SQL produced is
exec (#sql)
(Here's a SQL Fiddle link for this one; but it's not working despite the SQL being valid

Pivot outputs two values

create table #Contact(
LoanNumber int,
ContactType varchar(10),
CompanyName varchar(10),
CompanyPhone varchar(10),
CONSTRAINT PK PRIMARY KEY (LoanNumber,ContactType)
)
Insert into #Contact
values (1,'Appriaser','Yige King','11' ),
(1,'AssetOwner','gqqnbig','22' )
This is my table. ContactTypes are only Appriaser and AssetOwner.
Can I get a table like
LoanNumber AppraiserCompanyName AppraiserCompanyPhone AssertOwnerCompanyName AssertOwnerCompanyPhone
----------------------------------------------------------------------------------------------------
6103339 YigeKing 11 gqqnbig 22
I managed to write this
select LoanNumber,
CompanyNamePT.Appriaser as AppriaserCompanyName, CompanyNamePT.AssetOwner as AssetOwnerCompanyName
--CompanyPhonePT.Appriaser as AppriaserCompanyPhone, CompanyPhonePT.AssetOwner as AssetOwnerCompanyPhone
from (
select #contact.LoanNumber, #contact.ContactType, #contact.CompanyName
from #contact
) as c
pivot ( max(c.CompanyName) for c.ContactType in (Appriaser,AssetOwner)) as CompanyNamePT
--pivot ( max(c.CompanyPhone) for c.ContactType in ([Appriaser],[AssetOwner])) as CompanyPhonePT
It outputs company names, but if I uncomment the two lines to get phone number, it throws syntax error.
How can I make it work? Ideally I want to use pivot because I'm learnig it.
For the desired PIVOT
Select *
From (
Select C.LoanNumber
,B.*
From #Contact C
Cross Apply ( values (IIF(ContactType='Appriaser' ,'AppraiserCompanyName' , 'AssetOwnerCompanyName') ,C.CompanyName)
,(IIF(ContactType='Appriaser' , 'AppraiserCompanyPhone', 'AssetOwnerCompanyPhone'),C.CompanyPhone)
) B (Item,Value)
) A
pivot ( max(A.Value) for A.Item in ([AppraiserCompanyName],[AppraiserCompanyPhone],[AssetOwnerCompanyName],[AssetOwnerCompanyPhone]) ) P
But a Conditional Aggregation would do as well
Select C.LoanNumber
,AppraiserCompanyName = max(case when ContactType='Appriaser' then C.CompanyName end)
,AppraiserCompanyPhone = max(case when ContactType='Appriaser' then C.CompanyPhone end)
,AssetOwnerCompanyName = max(case when ContactType='AssetOwner' then C.CompanyName end)
,AssetOwnerCompanyPhone = max(case when ContactType='AssetOwner' then C.CompanyPhone end)
From #Contact C
Group By C.LoanNumber
Both Would Return
If it Helps with the Visualization, the sub-query with the Cross Apply Generates

Sql Partitioning

I have Sql Table data and i need to filter only the Consecutive dates blocks as i highlighted on image below..
.
and i need to add custom rates for each row on that selected blocks(this rate can display with separate column on out put).If there is more than 6 rows captured then $200 apply for each column of that block.if it is less than 6 ,it will be $125.The out put should be like this
And it should group by EmpID.
i need to get the out put using MSSQL. Can any one help me
this is what i have done through the sql view
ALTER view [dbo].[vw_Test2] AS
SELECT
tbl2.ID as Tbl2ID,
tbl1.[EmpID],
tbl1.[ExpInDateTime] as Tbl1ExpDate,
tbl2.[ExpInDateTime] as Tbl2ExpDate,
case when(CONVERT(date,tbl1.[ActInDateTime]) = CONVERT(date, DATEADD(DAY,1,tbl2.[ExpInDateTime]))) then
1
else 0
end as Token
from [dbo].[vw_Test] tbl1 join [dbo].[vw_Test] tbl2
on tbl1.ID=(tbl2.ID+1)
GO
only thing is i have to do this using SQL views
Please try this as a view:
ALTER VIEW [dbo].[vw_Test2] AS
WITH PreResult AS (
SELECT p.Id,p.EmpID,p.[DateTime],CASE WHEN LEAD(p.diff)OVER(ORDER BY p.Id) > 1 OR LEAD(p.EmpID)OVER(ORDER BY p.Id)<>p.EmpID THEN 1 ELSE 0 END StartNewGroup
FROM (
SELECT t.Id,t.EmpID,t.[DateTime], COALESCE(DATEDIFF(day,LAG(t.[DateTime])OVER(PARTITION BY t.EmpID ORDER BY t.Id),t.[DateTime]),1) [diff]
FROM [dbo].[vw_Test] t
) p
)
SELECT r.Id,r.EmpID,r.[DateTime]
,CASE WHEN COUNT(*)OVER(PARTITION BY r.NewGroup ORDER BY r.NewGroup) >= 6 THEN 250 ELSE 125 END [Rate]
FROM (
SELECT b.Id,b.EmpID,b.[DateTime],1+COALESCE((SELECT SUM(a.StartNewGroup) FROM PreResult a WHERE a.Id<b.Id),0) NewGroup
FROM PreResult b
) r
GO
There is also query to play with:
CREATE TABLE #Test (Id BIGINT IDENTITY(1,1),EmpID BIGINT, [DateTime] DATETIME)
INSERT INTO #Test (EmpID,[DateTime]) VALUES (5,'20150106'),(5,'20150107'),(5,'20150109'),
(5,'20150110'),(5,'20150126'),(5,'20150127'),
(5,'20150128'),(5,'20150129'),(5,'20150130'),
(5,'20150131'),(10,'20121203'),(10,'20121204'),
(10,'20121205'),(10,'20121206'),
(10,'20121207'),(10,'20121208'),(10,'20121209')
;WITH PreResult AS (
SELECT p.Id,p.EmpID,p.[DateTime],CASE WHEN LEAD(p.diff)OVER(ORDER BY p.Id) > 1 OR LEAD(p.EmpID)OVER(ORDER BY p.Id)<>p.EmpID THEN 1 ELSE 0 END StartNewGroup
FROM (
SELECT t.Id,t.EmpID,t.[DateTime], COALESCE(DATEDIFF(day,LAG(t.[DateTime])OVER(PARTITION BY t.EmpID ORDER BY t.Id),t.[DateTime]),1) [diff]
FROM #Test t
) p
)
SELECT r.Id,r.EmpID,r.[DateTime]
,CASE WHEN COUNT(*)OVER(PARTITION BY r.NewGroup ORDER BY r.NewGroup) >= 6 THEN 250 ELSE 125 END [Rate]
FROM (
SELECT b.Id,b.EmpID,b.[DateTime],1+COALESCE((SELECT SUM(a.StartNewGroup) FROM PreResult a WHERE a.Id<b.Id),0) NewGroup
FROM PreResult b
) r
DROP TABLE #Test
Please let me know if you have any questions.

Pivoting a table-valued function

I have a TVF that returns two columns: 'measure' (a name) and 'score', a numeric score for that measure:
dbo.ScoringFunction(param1, param2, ..., paramN)
Measure Score
------- -----
measure1 10
measure2 5
... ...
measureN 15
I'm running this function against a large number of rows that contain its parameters:
Name Param1 Param2 ... ParamN
---- ------ ------ ------
Daniel 12 5 6
etc.
I am trying to find a way to display the measures and their scores next to the parameters that determine those scores:
Name Param1 Param2 ... ParamN measure1 measure2 ... measureN
---- ------ ------ ------ -------- -------- --------
Daniel 12 5 6 10 5 15
etc.
So far I have tried using a pivot table, but it's tricky since the data being pivoted is contained in a TVF rather than a static table. I've also tried using CROSS APPLY, but once I have the data (measures & scores), I'm still unable to pivot it into a nicely formatted row.
If anybody has any ideas, they would be much appreciated!
Without changing too much (hopefully), I would do the pivoting in the function, then use the function in CROSS APPLY and pull the columns. So if your function is something like this:
CREATE FUNCTION dbo.ScoringFunction (parameters)
RETURNS TABLE
RETURN (
SELECT Measure, Score
FROM …
)
then I would rewrite it like this:
CREATE FUNCTION dbo.ScoringFunction (parameters)
RETURNS TABLE
RETURN (
WITH originalSelect AS (
SELECT Measure, Score
FROM …
)
SELECT
measure1,
measure2,
…
FROM originalSelect
PIVOT (
MAX(Score) FOR Measure IN (measure1, measure2, …)
) p
)
and use it in the final query like this:
SELECT
t.Name,
t.param1,
t.param2,
…
x.measure1,
x.measure2,
…
FROM atable t
CROSS APPLY dbo.ScoringFunction (t.param1, t.param2, …) x
If you make a function that looks like this:
CREATE FUNCTION [dbo].[fGetSpecificMeasures]
(
#HeightScore INT
, #WeightScore INT
, #TvScore INT
)
RETURNS TABLE
RETURN
(
SELECT
Final.Height AS tv_height_score
, Final.[Weight] AS tv_weight_score
, Final.TV AS tv_score
FROM
(
SELECT measure, score FROM ScoringRubric WHERE measure = 'Height' AND #HeightScore BETWEEN bottom_of_range AND top_of_range
UNION ALL
SELECT measure, score FROM ScoringRubric WHERE measure = 'Weight' AND #WeightScore BETWEEN bottom_of_range AND top_of_range
UNION ALL
SELECT measure, score FROM ScoringRubric WHERE measure = 'TV' AND #TvScore BETWEEN bottom_of_range AND top_of_range
) Base
PIVOT
(
MAX(score)
FOR measure
IN
(
[Height]
, [Weight]
, [TV]
)
) Final
);
GO
And one that looks like this:
CREATE FUNCTION [dbo].[fGetMeasureScore]
(
#Measure VARCHAR(50)
, #Value INT
)
RETURNS TABLE
RETURN
(
SELECT
score
FROM ScoringRubric
WHERE measure = #Measure
AND #Value BETWEEN bottom_of_range AND top_of_range
);
GO
Then you can get your data with either of the following:
DECLARE #User VARCHAR(50) = 'Daniel'
SELECT
UserProfile.*
, HeightScore.score AS tv_height_score
, WeightScore.score AS tv_weight_score
, TvScore.score AS tv_score
FROM UserProfile
INNER JOIN ScoringRubric HeightScore
ON HeightScore.measure = 'Height'
AND UserProfile.height BETWEEN HeightScore.bottom_of_range AND HeightScore.top_of_range
INNER JOIN ScoringRubric WeightScore
ON WeightScore.measure = 'Weight'
AND UserProfile.[weight] BETWEEN WeightScore.bottom_of_range AND WeightScore.top_of_range
INNER JOIN ScoringRubric TvScore
ON TvScore.measure = 'TV'
AND UserProfile.TV BETWEEN TvScore.bottom_of_range AND TvScore.top_of_range
WHERE UserProfile.name = #User
SELECT
*
FROM UserProfile
CROSS APPLY dbo.fGetSpecificMeasures(height, [weight], TV)
WHERE name = #User
SELECT
UP.*
, HeightScore.score AS tv_height_score
, WeightScore.score AS tv_weight_score
, TvScore.score AS tv_score
FROM UserProfile UP
CROSS APPLY fGetMeasureScore('Height', UP.height) HeightScore
CROSS APPLY fGetMeasureScore('Weight', UP.[weight]) WeightScore
CROSS APPLY fGetMeasureScore('TV', UP.TV) TvScore
WHERE UP.name = #User
I don't really know which one you'll find most appropriate for your uses. Let me know if you have questions.
As for your original question, if this were the function:
CREATE FUNCTION [dbo].[fGetMeasureScoresOriginal]
(
#HeightScore INT
, #WeightScore INT
, #TvScore INT
)
RETURNS TABLE
RETURN
(
SELECT measure, score FROM ScoringRubric WHERE measure = 'Height' AND #HeightScore BETWEEN bottom_of_range AND top_of_range
UNION ALL
SELECT measure, score FROM ScoringRubric WHERE measure = 'Weight' AND #WeightScore BETWEEN bottom_of_range AND top_of_range
UNION ALL
SELECT measure, score FROM ScoringRubric WHERE measure = 'TV' AND #TvScore BETWEEN bottom_of_range AND top_of_range
)
GO
Then you could write the query and pivot like so:
SELECT
Final.name
, Final.OriginalHeight AS height
, Final.OriginalWeight AS [weight]
, Final.OriginalTv AS TV
, Final.Height AS tv_height_score
, Final.[Weight] AS tv_weight_score
, Final.TV AS tv_score
FROM
(
SELECT
UP.name
, UP.height AS OriginalHeight
, UP.[weight] AS OriginalWeight
, UP.TV AS OriginalTv
, Measures.measure
, Measures.score
FROM UserProfile UP
CROSS APPLY dbo.fGetMeasureScoresOriginal(UP.height, UP.[weight], UP.TV) Measures
WHERE UP.name = #User
) Base
PIVOT
(
MAX(score)
FOR measure
IN
(
[Height]
, [Weight]
, [TV]
)
) Final
EDIT: Just realized I didn't answer the original question. Adding that now.
If you want to pivot a static set of rows you can use the technique as I described here.
Reposting the example, so it will be different tables, but the technique can be applied in your case as well I think.
SELECT
Customers.CustID,
MAX(CASE WHEN CF.FieldID = 1 THEN CF.FieldValue ELSE NULL END) AS Field1,
MAX(CASE WHEN CF.FieldID = 2 THEN CF.FieldValue ELSE NULL END) AS Field2,
MAX(CASE WHEN CF.FieldID = 3 THEN CF.FieldValue ELSE NULL END) AS Field3,
MAX(CASE WHEN CF.FieldID = 4 THEN CF.FieldValue ELSE NULL END) AS Field4
-- Add more...
FROM Customers
LEFT OUTER JOIN CustomFields CF
ON CF.ID = Customers.CustID
WHERE Customers.CustName like 'C%'
GROUP BY Customers.CustID