Транспонирование групп строк с одинаковым идентификатором в другую таблицу - PullRequest
0 голосов
/ 09 января 2019

У меня есть таблица, Demo1, где у меня есть несколько похожих DIM_KEY для нескольких разных ATTR_NAME (имен атрибутов). Я хочу отобразить таблицу со столбцами для DIM_KEY, UPC, DAIRY_CLM, KOSHER_CLM, FAT и CALORIES, где совпадающими значениями являются строки.

Это оригинальная таблица Demo1: [1]: https://imgur.com/a/KqayM1C



Вот как я хочу, чтобы это выглядело (таблица: Demo2): [2]: https://imgur.com/a/nwpoHhv

Я пытался вставить строки из Demo1 в пустую таблицу Demo2, но это не сработало так, как я этого хотел. Я также не мог получить DIM_KEY таким образом. Я также пытался использовать PIVOT, но получил только ошибки. Я использую MySQL, но это также должно работать в SSMS. Предпочтительно SSMS, если мне нужно было выбрать один.

INSERT INTO Demo2 (UPC, DAIRY_CLM, KOSHER_CLM, FAT, CALORIES)
SELECT
    (CASE WHEN ATTR_NAME = 'UPC' THEN VALUE END),
    (CASE WHEN ATTR_NAME = 'DAIRY_CLM' THEN VALUE END),
    (CASE WHEN ATTR_NAME = 'KOSHER_CLM' THEN VALUE END),
    (CASE WHEN ATTR_NAME = 'FAT' THEN VALUE END),
    (CASE WHEN ATTR_NAME = 'CALORIES' THEN VALUE END)
FROM Demo1;

Ответы [ 2 ]

0 голосов
/ 09 января 2019

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

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

Если это утешит, вы были действительно близко!

SELECT
    DIM_KEY,
    MAX(CASE WHEN ATTR_NAME = 'UPC' THEN VALUE END) as UPC,
    MAX(CASE WHEN ATTR_NAME = 'DAIRY_CLM' THEN VALUE END) as DAIRY_CLM,
    MAX(CASE WHEN ATTR_NAME = 'KOSHER_CLM' THEN VALUE END) as KOSHER_CLM,
    MAX(CASE WHEN ATTR_NAME = 'FAT' THEN VALUE END) as FAT,
    MAX(CASE WHEN ATTR_NAME = 'CALORIES' THEN VALUE END) as CALORIES
FROM demo
GROUP BY DIM_KEY

Как это работает?

Что ж, если вы запустите несгруппированную версию без функций, которая у вас уже была:

SELECT
    DIM_KEY,
    (CASE WHEN ATTR_NAME = 'UPC' THEN VALUE END),
    (CASE WHEN ATTR_NAME = 'DAIRY_CLM' THEN VALUE END),
    (CASE WHEN ATTR_NAME = 'KOSHER_CLM' THEN VALUE END),
    (CASE WHEN ATTR_NAME = 'FAT' THEN VALUE END),
    (CASE WHEN ATTR_NAME = 'CALORIES' THEN VALUE END)
FROM
   demo

Тогда вы увидите, что ваши данные станут «диагональными»:

3005, 123423, null, null...
3005, null,   N,    null...
3005, null,   null, Y   ...

В каждом столбце (для каждого dim_key) есть только одно значение, остальные - NULL

Добавление в GROUP BY и MAX приводит к тому, что они сворачиваются в одну строку, потому что MAX () вернет только значение из столбца и заставит все нули исчезнуть. Это внутреннее свойство группировки, что данные строки не «остаются вместе» - в группе определенного DIM_KEY MAX (DAIRY_CLM) может поступать из любой строки, MAX (KOSHER_CLM) может поступать из любой другой строки. На практике это означает, что отдельные значения выбираются, нули отбрасываются, все они появляются в одной строке.

.. и, таким образом, ваши вертикальные данные перешли в горизонтальное положение после прохождения диагонали

0 голосов
/ 09 января 2019

Вы можете использовать (ложную) функцию агрегирования и группировать по

INSERT INTO Demo2 (UPC, DAIRY_CLM, KOSHER_CLM, FAT, CALORIES)
SELECT min(CASE WHEN ATTR_NAME = 'UPC' THEN VALUE END) ,
      min(CASE WHEN ATTR_NAME = 'DAIRY_CLM' THEN VALUE END),
     min(CASE WHEN ATTR_NAME = 'KOSHER_CLM' THEN VALUE END),
    min(CASE WHEN ATTR_NAME = 'FAT' THEN VALUE END),
    min(CASE WHEN ATTR_NAME = 'CALORIES' THEN VALUE END)
FROM Demo1
group by DIM_KEY; 

это должно работать одинаково для обеих баз данных.

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