Объединить столбцы и заменить значение NULL - PullRequest
3 голосов
/ 09 марта 2020

DB-Fiddle

CREATE TABLE logistics (
    id int primary key,
    campaign VARCHAR(255),
    event_type VARCHAR (255),
    date_offered DATE,
    date_ordered DATE, 
    date_delivered DATE,
    quantity VARCHAR(255)
);

INSERT INTO logistics
(id, campaign, event_type, 
date_offered, date_ordered, date_delivered, quantity
)
VALUES 
("1", "C001", "offered", "2019-04-10", NULL, NULL, "500"),
("2", "C001", "ordered", NULL, "2019-04-16", NULL, "450"),
("3", "C001", "stored", NULL, NULL, "2019-04-18", NULL),

("4", "C002", "offered", "2019-08-14", NULL, NULL, "700"),
("5", "C002", "ordered", NULL, "2019-09-04", NULL, "730"),
("6", "C002", "stored", NULL, NULL, "2019-09-15", "800");

Я хочу выполнить запрос, coalesce значения которого так:

a) все date values находятся в одном столбце с именами event_date и
b) в случае, если quantity для event_type stored (как вы можете видеть для C001) нет quantity event_type order следует использовать.

Результат должен выглядеть следующим образом:

campaign     event_type       event_date         quantity
C001         offered          2019-04-10          500
C001         ordered          2019-04-16          450
C001         stored           2019-04-18          450
C002         offered          2019-08-14          700
C002         ordered          2019-09-04          730
C002         stored           2019-09-15          800

Я пытался go с этим:

SELECT id,
       campaign,
       event_type,
       coalesce(date_offered, date_ordered, date_delivered) as event_date,
       quantity
  FROM logistics;

С этот запрос приближается к моим ожидаемым результатам, но для C001 в event_type stored есть NULL для C001.

Как мне нужно изменить свой запрос, чтобы получить quantity из event_type ordered для event_type stored для C001?

Ответы [ 4 ]

1 голос
/ 09 марта 2020

Вы можете использовать logi c, аналогичный self join, для таблицы logistics, где часть после условия JOIN будет вложенным запросом, отфильтрованным по event_type = 'ordered' и сгруппированным по столбцу campaign:

SELECT id, l1.campaign, event_type,
       COALESCE(date_offered, date_ordered, date_delivered) AS event_date,
       COALESCE(l1.quantity,l2.quantity) AS quantity 
  FROM logistics l1
  JOIN ( SELECT campaign, MAX(quantity) AS quantity 
           FROM logistics 
          WHERE event_type = 'ordered' 
          GROUP BY campaign  )  l2
    ON l2.campaign = l1.campaign      

Демо

1 голос
/ 09 марта 2020

Вы можете использовать коррелированный подзапрос:

SELECT l.id, l.campaign, l.event_type,
       coalesce(l.date_offered, l.date_ordered, l.date_delivered) as event_date,
       coalesce(l.quantity,
                      (SELECT MAX(l1.quantity)
                       FROM logistics l1
                       WHERE l1.event_type = 'ordered' AND l.campaign = l1.campaign
                      )
               ) as new_quantity
FROM logistics l;
0 голосов
/ 09 марта 2020

FWIW, мне кажется, что это лучшая схема:

+----+----------+------------+------------+----------+
| id | campaign | event_type | event_date | quantity |
+----+----------+------------+------------+----------+
|  1 |    1     | offered    | 2019-04-10 | 500      |
|  2 |    2     | offered    | 2019-08-14 | 700      |
|  3 |    1     | ordered    | 2019-04-16 | 450      |
|  4 |    2     | ordered    | 2019-09-04 | 730      |
|  5 |    1     | stored     | 2019-04-18 | NULL     |
|  6 |    2     | stored     | 2019-09-15 | 800      |
+----+----------+------------+------------+----------+
0 голосов
/ 09 марта 2020

Вы можете использовать функции окна:

SELECT id, campaign, event_type,
       coalesce(date_offered, date_ordered, date_delivered) as event_date,
       coalesce(quantity,
                max(case when event_type = 'ordered' then quantity end) over (partition by campaign)
               ) as new_quantity
FROM logistics;

В более старых версиях вы можете использовать JOIN:

SELECT l.id, l.campaign, l.event_type,
       coalesce(l.date_offered, l.date_ordered, l.date_delivered) as event_date,
       coalesce(l.quantity, lo.quantity
               ) as new_quantity
FROM logistics l LEFT JOIN
     (SELECT lo.campaign, MAX(lo.quantity) as quantity
      FROM logistics lo
      WHERE lo.event_type = 'ordered'
      GROUP BY lo.campaign
     ) lo
     USING (campaign);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...