Почему я получаю 4 строки в Pivot? - PullRequest
2 голосов
/ 06 июня 2019

Поворот данных

Поворот - это метод, который группирует и объединяет данные, переводя их из состояния строк в состояние столбцов.Во всех сводных запросах необходимо указать три элемента:

  • Что вы хотите видеть в строках?Этот элемент известен как включенные строки или группирующий элемент
  • Что вы хотите видеть в столбцах?Этот элемент известен как столбцы на столбцах или распространяющийся элемент .
  • Что вы хотите видеть на пересечении каждой отдельной строки и значения столбца?Этот элемент известен как данные или элемент агрегации .

pattern:

WITH PivotData AS
(
  SELECT
    < grouping column >,
    < spreading column >,
    < aggregation column >
  FROM < source table >
)
SELECT < select list >
FROM PivotData
  PIVOT( < aggregate function >(< aggregation column >)
    FOR < spreading column > IN (< distinct spreading values >) ) AS P;

У меня есть эта таблица, созданная в SQL Server

CREATE TABLE [dbo].[NameValueData](
    [Name] [VARCHAR](50) NOT NULL,
    [Value] [INT] NOT NULL
) ON [PRIMARY]

и имеет значения

INSERT INTO NameValueData
VALUES
( 'N1', 1 ), 
( 'N2', 2 ), 
( 'N3', 3 ), 
( 'N4', 4 ),
--NOT FIXED Number of ROWS

И данные:

Name    Value
N1  1
N2  2
N3  3
N4  4
... ...

Теперь мне нужно повернуть этих данных и получить результаты там, где имена столбцовсоздан на основе значений строки из имени столбца

N1  N2  N3  N4  ...
1   2   3   4   --Can be more

Я пытался написать свой собственный сводный SQL

WITH PivotData
AS (SELECT Value AS GroupingColumn,
           Name AS SpreadingColumn,
           Value AS AggregationColumn
    FROM dbo.NameValueData)
SELECT 1 AS Ignore,
       [N1],
       [N2],
       [N3],
       [N4]
FROM PivotData
    PIVOT
    (
        MAX(AggregationColumn)
        FOR SpreadingColumn IN ([N1], [N2], [N3], [N4])
    ) AS P;

Результат:

Ignore  N1  N2  N3  N4
1   1   NULL    NULL    NULL
1   NULL    2   NULL    NULL
1   NULL    NULL    3   NULL
1   NULL    NULL    NULL    4

Почему я получаю 4строк здесь?

Ответы [ 3 ]

2 голосов
/ 06 июня 2019

Если вы замените 1 AS Ignore в списке выбора на GroupingColumn, вы поймете, почему вы получаете 4 записи вместо одной.

В операции PIVOT используются все столбцы группировки, независимо от того, включены ли онив окончательном прогнозе или не в подразумеваемом предложении group by при выполнении агрегации.

Удаление GroupingColumn из PivotData CTE и из окончательного прогноза решит вашу проблему.

Фактически из-за характера ваших данных вы можете полностью избавиться от CTE и просто использовать этот запрос:

select * 
  from namevaluedata
 pivot (max(value)
        for name in ([N1], [N2], [N3], [N4])
       ) p;
1 голос
/ 08 июня 2019

Попробуйте это:

WITH PivotData
AS (SELECT Name AS SpreadingColumn,
           Value AS AggregationColumn
    FROM dbo.NameValueData)
SELECT 1 AS Ignore,
       [N1],
       [N2],
       [N3],
       [N4]
FROM PivotData
    PIVOT
    (
        MAX(AggregationColumn)
        FOR SpreadingColumn IN ([N1], [N2], [N3], [N4])
    ) AS P;
0 голосов
/ 06 июня 2019

Мне просто не нравится pivot, и я очень предпочитаю условную агрегацию.И это одна из причин.

Генерируемые строки определяются всеми значениями в исходных данных, которые не в предложении PIVOT.Поскольку у вас есть третий столбец (GroupingColumn), он используется для определения строк.

...