SQL Один ко многим запрос в одну строку - PullRequest
0 голосов
/ 12 февраля 2019

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

таблица продуктов

|----|------|
| id | name |
|----|------|
| 12 | foo  |
|----|------|

таблица product_manufacturer

|----|------------|------------------|---------------------------|
| id | product_id |  manufacturer_id | manufacturer_product_code |
|----|------------|------------------|---------------------------|
| XX |     12     |       ABCD       |          X1X2             |
|----|------------|------------------|---------------------------|
| YY |     12     |       LMKO       |          AAAB             |
|----|------------|------------------|---------------------------|

желаемый результат:

+------+-------------+--------------------+--------------------+--------------------+--------------------+
| name | internal_id | manufacturer1_code | manufacturer2_code | manufacturer3_code | manufacturer4_code |
+------+-------------+--------------------+--------------------+--------------------+--------------------+
| foo  |          12 | X1X2               | null               | AAAB               | null               |
+------+-------------+--------------------+--------------------+--------------------+--------------------+

Я пробовал это:

     SELECT p.`name` AS product, p.`id` AS internal_id, 
          (
           SELECT pm.`manufacturer_product_code`
             FROM  `product_manufacturer` pm
            WHERE pm.`manufacturer_id` internal_id 
              AND pm.`manufacturer_id` LIKE 'ABCD'
        ) AS manufacturer1_code,
        (
           SELECT pm.`manufacturer_product_code`
             FROM  `product_manufacturer` pm
            WHERE pm.`manufacturer_id` LIKE internal_id 
              AND pm.`manufacturer_id` LIKE 'CDCD'
       ) AS manufacturer2_code,
          (
           SELECT pm.`manufacturer_product_code`
             FROM  `product_manufacturer` pm
            WHERE pm.`manufacturer_id` LIKE internal_id 
              AND pm.`manufacturer_id` LIKE 'LMKO'
          ) AS manufacturer3_code,
          (
           SELECT pm.`manufacturer_product_code`
             FROM  `product_manufacturer` pm
            WHERE pm.`manufacturer_id` LIKE internal_id 
              AND pm.`manufacturer_id` LIKE 'RSRS'
            ) AS manufacturer4_code
       FROM `product_manufacturer` pm 
 INNER JOIN `products` p 
         ON p.`id`=pm.`product_id`

Это возвращает первые два столбца хорошо, но остальные четыре возвращают ноль.
Когда язаставить его работать, я должен использовать Group by p.name

Какой правильный путь?Спасибо.

1 Ответ

0 голосов
/ 12 февраля 2019

Один из способов сделать это - с помощью имитации row_number

DROP TABLE IF EXISTS T,T1;
CREATE TABLE T (ID INT, NAME VARCHAR(10));
CREATE TABLE T1( id varchar(2), product_id int,  manufacturer_id varchar(20), manufacturer_product_code varchar(20));

insert into t values(12,'foo');
insert into t1 values
('XX' ,     12     ,       'ABCD'       ,          'X1X2'),
('YY' ,     12     ,       'LMKO'       ,          'AAAB');

select t.name,t.id,
        max(case when rownumber = 1 then manufacturer_product_code else '' end) man1,
        max(case when rownumber = 2 then manufacturer_product_code else '' end) man2,
        max(case when rownumber = 3 then manufacturer_product_code else '' end) man3,
        max(case when rownumber = 4 then manufacturer_product_code else '' end) man4
from t
join
(
select t1.*,
         if(t1.product_id <> @p,@rn:=1,@rn:=@rn+1) rownumber,
         @p:=t1.product_id p
from t1
cross join (select @rn:=0,@p:=0) r
order by t1.product_id,t1.id
) s
on s.product_id = t.id
group by t.name,t.id;

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

+------+------+------+------+------+------+
| name | id   | man1 | man2 | man3 | man4 |
+------+------+------+------+------+------+
| foo  |   12 | X1X2 | AAAB |      |      |
+------+------+------+------+------+------+
1 row in set (0.00 sec)

Если у вас версия 8 или выше, вы можете использовать оконную функцию row_number вместо симуляции с использованием переменных в подзапросе.

...