8

1つの列(数値列)をピボットする必要があります。例にはこのデータが必要です:

a 1
a 2
b 3
b 4
c 5
d 6
d 7
d 8
d 9
e 10
e 11
e 12
e 13
e 14

こんな風に見える

a 1 2
b 3 4
c 5
d 6 7 8 9
e 10 11 12 13 14

どんな助けでも大歓迎です...

4

5 に答える 5

14

ROW_NUMBER()PIVOTおよびいくつかの動的 SQL を使用する (ただし、カーソルは必要ありません) :

CREATE TABLE [dbo].[stackoverflow_198716](
    [code] [varchar](1) NOT NULL,
    [number] [int] NOT NULL
) ON [PRIMARY]

DECLARE @sql AS varchar(max)
DECLARE @pivot_list AS varchar(max) -- Leave NULL for COALESCE technique
DECLARE @select_list AS varchar(max) -- Leave NULL for COALESCE technique

SELECT @pivot_list = COALESCE(@pivot_list + ', ', '') + '[' + CONVERT(varchar, PIVOT_CODE) + ']'
        ,@select_list = COALESCE(@select_list + ', ', '') + '[' + CONVERT(varchar, PIVOT_CODE) + '] AS [col_' + CONVERT(varchar, PIVOT_CODE) + ']'
FROM (
    SELECT DISTINCT PIVOT_CODE
    FROM (
        SELECT code, number, ROW_NUMBER() OVER (PARTITION BY code ORDER BY number) AS PIVOT_CODE
        FROM stackoverflow_198716
    ) AS rows
) AS PIVOT_CODES

SET @sql = '
;WITH p AS (
    SELECT code, number, ROW_NUMBER() OVER (PARTITION BY code ORDER BY number) AS PIVOT_CODE
    FROM stackoverflow_198716
)
SELECT code, ' + @select_list + '
FROM p
PIVOT (
    MIN(number)
    FOR PIVOT_CODE IN (
        ' + @pivot_list + '
    )
) AS pvt
'

PRINT @sql

EXEC (@sql)
于 2008-10-14T01:56:54.580 に答える
1

データの連結について尋ねられた他の質問と同様に、coalesce 関数もここで使用できます。

サブクエリからの複数の行を単一の区切りフィールドに「結合」するSQL Server関数を作成する方法は?

于 2008-10-13T20:44:41.120 に答える
1

この関連する質問には、必要な答えが含まれているはずです: SQL Server: Examples of PIVOTing String data

SSRS のマトリックス コントロールには動的な列があります。このデータがレポートにバインドされている場合は、それを使用できます。それ以外の場合は、例のように sql を動的に生成して実行する sql sproc を作成する必要があります。

于 2008-10-13T20:16:18.260 に答える
1

CTE についてもう少し経験を積みたいという理由だけで、次のことを思いつきました。

WITH CTE(CTEstring, CTEids, CTElast_id)
AS
(
    SELECT string, CAST(id AS VARCHAR(1000)), id
    FROM dbo.Test_Pivot TP1
    WHERE NOT EXISTS (SELECT * FROM dbo.Test_Pivot TP2 WHERE TP2.string = TP1.string AND TP2.id < TP1.id)
    UNION ALL
    SELECT CTEstring, CAST(CTEids + ' ' + CAST(TP.id AS VARCHAR) AS VARCHAR(1000)), TP.id
    FROM dbo.Test_Pivot TP
    INNER JOIN CTE ON
        CTE.CTEstring = TP.string
    WHERE
        TP.id > CTE.CTElast_id AND
        NOT EXISTS (SELECT * FROM dbo.Test_Pivot WHERE string = CTE.CTEstring AND id > CTE.CTElast_id AND id < TP.id)
)
SELECT
    t1.CTEstring, t1.CTEids
FROM CTE t1
INNER JOIN (SELECT CTEstring, MAX(LEN(CTEids)) AS max_len_ids FROM CTE GROUP BY CTEstring) SQ ON SQ.CTEstring = t1.CTEstring AND SQ.max_len_ids = LEN(t1.CTEids)
ORDER BY CTEstring
GO

微調整が必​​要かもしれませんが、あなたの例ではうまくいきました

于 2008-10-13T20:29:52.867 に答える
0

あなたがやっていることは、SQL で実際に可能である (または少なくとも実用的である) かどうかはわかりません。

たとえば、次のように、クライアント アプリケーションでそのピボット テーブルを作成できます。

select distinct Letter from MyTable

文字のリストを取得し、ループ内でパラメーター化されたクエリを使用します。

select Number from MyTable where Letter=:letter

各文字の数字のリストを取得します。

于 2008-10-13T21:09:42.897 に答える