ROW_NUMBER()関数を使用して、各検索結果アイテムに各検索結果内のランクを与えることができます。
SELECT SearchResultItemID,
SearchResultID,
Name,
Value,
RowNumber = ROW_NUMBER() OVER(PARTITION BY SearchResultID ORDER BY SearchresultItemID)
FROM SearchResultItem;
アイテムの数がわかっている場合は、集計関数を使用して各名前/値のペアを取得できます。
WITH RankedItem AS
( SELECT SearchResultItemID,
SearchResultID,
Name,
Value,
RowNumber = ROW_NUMBER() OVER(PARTITION BY SearchResultID ORDER BY SearchresultItemID)
FROM SearchResultItem
)
SELECT SearchResultID,
Name1 = MIN(CASE WHEN RowNumber = 1 THEN Name END),
Value1 = MIN(CASE WHEN RowNumber = 1 then Value END),
Name2 = MIN(CASE WHEN RowNumber = 2 THEN Name END),
Value2 = MIN(CASE WHEN RowNumber = 2 then Value END),
Name3 = MIN(CASE WHEN RowNumber = 3 THEN Name END),
Value3 = MIN(CASE WHEN RowNumber = 3 then Value END),
Name4 = MIN(CASE WHEN RowNumber = 4 THEN Name END),
Value5 = MIN(CASE WHEN RowNumber = 4 then Value END)
FROM RankedItem
GROUP BY SearchResultID;
次に、これを検索結果テーブルに結合して、完全なクエリを提供できます。
WITH RankedItem AS
( SELECT SearchResultItemID,
SearchResultID,
Name,
Value,
RowNumber = ROW_NUMBER() OVER(PARTITION BY SearchResultID ORDER BY SearchresultItemID)
FROM SearchResultItem
), Items AS
( SELECT SearchResultID,
Name1 = MIN(CASE WHEN RowNumber = 1 THEN Name END),
Value1 = MIN(CASE WHEN RowNumber = 1 then Value END),
Name2 = MIN(CASE WHEN RowNumber = 2 THEN Name END),
Value2 = MIN(CASE WHEN RowNumber = 2 then Value END),
Name3 = MIN(CASE WHEN RowNumber = 3 THEN Name END),
Value3 = MIN(CASE WHEN RowNumber = 3 then Value END),
Name4 = MIN(CASE WHEN RowNumber = 4 THEN Name END),
Value4 = MIN(CASE WHEN RowNumber = 4 then Value END)
FROM RankedItem
GROUP BY SearchResultID
)
SELECT SearchResult.SearchResultID,
SearchResult.ProductID,
SearchResult.SearchQuery,
SearchResult.WebsiteName,
SearchResult.URL,
SearchResult.IsFound,
SearchResult.CreatedOn,
SearchResult.BatchID,
SearchResult.Name,
Items.Name1,
Items.Value1,
Items.Name2,
Items.Value2,
Items.Name3,
Items.Value3,
Items.Name4,
Items.Value4
FROM SearchResult
INNER JOIN Items
ON SearchResult.SearchResultID = Items.SearchResultID;
SQL Fiddle の例
可変数の値を返したい場合は、動的 SQL を使用する必要があります。
DECLARE @SQL NVARCHAR(MAX) = '';
SELECT @SQL = @SQL + ',[Name' + rn + '], [Value' + rn + '] '
FROM ( SELECT DISTINCT
rn = CAST(ROW_NUMBER() OVER(PARTITION BY SearchResultID ORDER BY SearchresultItemID) AS VARCHAR)
FROM SearchResultItem
) p;
SET @SQL = 'WITH RankedItem AS
( SELECT SearchResultItemID,
SearchResultID,
Name,
Value,
RowNumber = ROW_NUMBER() OVER(PARTITION BY SearchResultID ORDER BY SearchresultItemID)
FROM SearchResultItem
), UnPivoted AS
( SELECT upvt.SearchResultID,
Name = upvt.n + CAST(RowNumber AS VARCHAR),
upvt.v
FROM RankedItem
UNPIVOT
( n
FOR v IN ([Name], [Value])
) upvt
), Pivoted AS
( SELECT *
FROM UnPivoted
PIVOT
( MAX(V)
FOR Name IN (' + STUFF(@SQL, 1, 1, '') + ')
) pvt
)
SELECT SearchResult.SearchResultID,
SearchResult.ProductID,
SearchResult.SearchQuery,
SearchResult.WebsiteName,
SearchResult.URL,
SearchResult.IsFound,
SearchResult.CreatedOn,
SearchResult.BatchID,
SearchResult.Name' + @SQL + '
FROM SearchResult
INNER JOIN Pivoted
ON SearchResult.SearchResultID = Pivoted.SearchResultID;';
EXECUTE SP_EXECUTESQL @SQL;
SQL Fiddle の例
注意:行を結合した結果を達成する方法が複数あることを示すために、動的SQLでこれを行う別の方法を意図的に使用しました。