Поворот или преобразование таблицы SQL - PullRequest
3 голосов
/ 03 февраля 2012

У меня есть таблица данных, подобная следующей

User Year  Points  Value
A    1997  1       10
A    1997  2       30
A    1997  3       40
A    1999  1       70
B    1993  1       7
B    1993  3       4
C    2001  1       10
.....

Я хочу, чтобы таблица была преобразована следующим образом:

User   Year  Points1  Points2  Points3 ....
A      1997  10       30       40
A      1999  70       null     null
B      1993  7        null     4
C      2001  10       null     null
......

Диапазон точек неизвестен во время компиляции, поэтому он не только от 1 до 3. Это почти как создание Точек в качестве заголовка столбца в новой таблице. Я думаю, что SQL PIVOT - хороший вариант, но мне не повезло, играя с ним. Я использую SQL 2008.

Ответы [ 2 ]

2 голосов
/ 03 февраля 2012

Поскольку вы упомянули SQL PIVOT Я предполагаю, что вы используете SQL Server 2005 или более позднюю версию или Oracle 11g

SQL 2005

SELECT [user], year, [1] as Point1, [2] as Point2, [3] as Point3 
FROM
(

SELECT  [user], year , points, Value
    FROM table ) AS SourceTable
PIVOT
(
SUM(Value)
FOR Points IN ([1], [2], [3])
) AS PivotTable
ORDER BY [user]

см. Рабочий пример по этому запросу data.se

Oracle 11g

Если вы используете Oracle 11g, это будет примерно так (не уверен насчет псевдонима поля)

SELECT *
FROM   (
        SELECT  user, year , points, Value
        FROM table )
PIVOT  (SUM(Value) AS sum_value FOR (Points ) IN ('1' as Point1 , 
                                                  '2' as Point2, 
                                                 '3' as Point3))
Order by User;
0 голосов
/ 04 февраля 2012

Может быть, это поможет:

Сначала создайте несколько тестовых данных:

CREATE TABLE tblPoints ([User] VARCHAR(100), [Year] INT,Points INT,Value INT)
INSERT INTO tblPoints
SELECT 'A',1997,1,10 UNION ALL
SELECT 'A',1997,2,30 UNION ALL
SELECT 'A',1997,3,40 UNION ALL
SELECT 'A',1999,1,70 UNION ALL
SELECT 'B',1993,1,7 UNION ALL
SELECT 'B',1993,3,4 UNION ALL
SELECT 'C',2001,1,10

Конкурирующие столбцы:

DECLARE @cols VARCHAR(MAX)
SELECT  @cols = COALESCE(@cols + ','+QUOTENAME('Points'+Points),
                     QUOTENAME('Points'+Points))
FROM
    (
        SELECT
            ROW_NUMBER() OVER(PARTITION BY tblPoints.Points ORDER BY tblPoints.Points) AS RowNbr,
            CAST(tblPoints.Points AS VARCHAR(5)) AS Points
        FROM 
            tblPoints
    ) AS tbl
WHERE
    tbl.RowNbr=1

Затем создайте динамический sql и выполните его:

DECLARE @query NVARCHAR(4000)=
N'SELECT
    *
FROM
(
    SELECT
        tblPoints.[User],
        tblPoints.[Year],
        ''Points''+CAST(tblPoints.Points AS VARCHAR(5)) AS Points,
        tblPoints.Value
    FROM
        tblPoints
) AS p
PIVOT
(
    SUM(Value) FOR Points IN('+@cols+')
) AS pvt
ORDER BY [User]'

EXECUTE(@query)

И потому, что я не хочу таблицу точек:

DROP TABLE tblPoints
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...