MySQL динамическая сводка

У меня есть таблица частей продукта, как это:

Части

part_id      part_type      product_id
--------------------------------------
1            A              1
2            B              1
3            A              2
4            B              2
5            A              3
6            B              3

и мне нужен запрос, который вернет такую ​​таблицу:

product_id      part_A_id      part_B_id
----------------------------------------
1               1              2
2               3              4
3               5              6

В его реальной реализации будут миллионы частей продукта


person Vaughan    schedule 27.09.2012    source источник
comment
Что вы пробовали?   -  person ruakh    schedule 28.09.2012
comment
То, что вы ищете, обычно называют динамическим поворотом.   -  person Joe Stefanelli    schedule 28.09.2012
comment
Сколько существует типов деталей?   -  person Lamak    schedule 28.09.2012
comment
@ruakh ничего красивого или полезного, я так много забыл mysql   -  person Vaughan    schedule 28.09.2012
comment
@Lamak Будет около 20 частей продукта   -  person Vaughan    schedule 28.09.2012
comment
@JoeStefanelli Будут ли теперь динамические повороты Google?   -  person Vaughan    schedule 28.09.2012
comment
SQL Server или MySQL или что-то другое?   -  person PeteGO    schedule 28.09.2012
comment
Re: ничего красивого или полезного: часть смысла демонстрации того, что вы пробовали, состоит в том, чтобы просто показать, что вы пробовали что-то. (Многие задающие вопросы этого не делают, и может быть трудно вызвать мотивацию, чтобы помочь этим людям!) Другая часть заключается в том, чтобы помочь прояснить вопрос; если вы публикуете запрос, который вы уже написали, и объясняете, почему он не делает то, что вам нужно, даже если он не приближается к этому, то это может помочь прояснить, что именно вам нужно.   -  person ruakh    schedule 28.09.2012
comment
@ruakh Я слышу, что ты говоришь. В данном случае я думал, что моя попытка мало что даст, кроме как замутит воду.   -  person Vaughan    schedule 28.09.2012
comment
возможный дубликат сводной строки MySQL в динамическое количество столбцов   -  person RichardTheKiwi    schedule 03.05.2013
comment
возможный дубликат сводной таблицы MySQL   -  person    schedule 15.08.2014


Ответы (3)


К сожалению, в MySQL нет функции PIVOT, но вы можете смоделировать ее, используя агрегатную функцию и оператор CASE. Для динамической версии вам нужно будет использовать подготовленные операторы:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when part_type = ''',
      part_type,
      ''' then part_id end) AS part_',
      part_type, '_id'
    )
  ) INTO @sql
FROM
  parts;
SET @sql = CONCAT('SELECT product_id, ', @sql, ' 
                  FROM parts 
                   GROUP BY product_id');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

См. скрипт SQL с демонстрацией

Если у вас было всего несколько столбцов, вы можете использовать статическую версию:

select product_id,
  max(case when part_type ='A' then part_id end) as Part_A_Id,
  max(case when part_type ='B' then part_id end) as Part_B_Id
from parts
group by product_id
person Taryn    schedule 27.09.2012
comment
Почему Макс здесь? Это потому, что там должна быть совокупная функция, а также может быть сумма или что-то еще? - person Harlsten; 29.01.2016
comment
@Harlsten Для этого должна быть агрегатная функция. sum не имеет смысла, потому что это part_id, для этого конкретного примера вам нужно будет использовать max или min. - person Taryn; 29.01.2016

В SQL Server есть ключевое слово PIVOT, но с MySQL вам нужно будет использовать либо множество операторов CASE/IF, либо множество JOIN.

Вот предыдущий пост о том, как это сделать.

person PeteGO    schedule 27.09.2012

просто сошлитесь на него дважды - (здесь у вас нет особого вопроса)

select a.product_id, a.part_id "part_a_id", b.part_id "part_b_id"
from parts a, parts b
where a.product_id = b.product_id
person Randy    schedule 27.09.2012
comment
Я думаю, вы неправильно прочитали вопрос. Вы должны вернуться и пересмотреть его пример. - person ajon; 28.09.2012
comment
я думаю, что это дает запрошенные результаты. вопрос плохой имхо. - person Randy; 28.09.2012
comment
Если я не ошибаюсь, это дает дополнительные результаты, которых нет в его результатах. Например: он создаст строку с (1,1,1), а также (1,1,2), а также (1,2,1) и (1,2,2). - person ajon; 28.09.2012