次のような関数を作成する場合:
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
そして、このように見えるもの:
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
次に、次のいずれかを使用してデータを取得できます。
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
どちらがあなたの用途に最も適しているかはわかりません。ご不明な点がございましたら、お気軽にお問い合わせください。
あなたの元の質問に関しては、これが機能だった場合:
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
次に、クエリを記述して、次のようにピボットできます。
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
編集:私が元の質問に答えなかったことに気づきました。今それを追加します。