Добавить новый столбец и заменить значения NULL - PullRequest
3 голосов
/ 11 марта 2020

DB-Fiddle

CREATE TABLE PDW_FCT_Logistics (

    id INT primary key,
    cID VARCHAR(255),
    event_type VARCHAR (255),
    delivery_estimate DATE,
    delivered_time DATE,
    complete_time DATE,
    plan_offer_quantity INT,
    order_quantity INT, 
    received INT
);

INSERT INTO PDW_FCT_Logistics
(id, cID, event_type,
delivery_estimate, delivered_time, complete_time,
plan_offer_quantity, order_quantity, received
)
VALUES 
("1", "46902", "offer", "2020-02-03", NULL, NULL, "6145", NULL, NULL),
("2", "46902", "order", "2020-02-03", NULL, NULL, NULL, "2145", NULL),
("3", "46902", "stock_in", "2020-02-03", "2020-02-10", NULL, NULL, NULL, NULL),

("4", "55519", "offer", "2020-05-09", NULL, NULL, "4337", NULL, NULL),
("5", "55519", "order", "2020-05-09", NULL, NULL, NULL, "4018", NULL),
("6", "55519", "stock_in", "2020-05-09", "2020-05-12", "2020-07-08", NULL, NULL, "3989");

Я хочу изменить структуру приведенной выше таблицы следующим образом:

id      cID        event_type     sub_event_type      event_date           quantity
1       46902      offer          NULL                2020-02-03            6145
2       46902      order          NULL                2020-02-03            2145
3       46902      stock_in       delivered           2020-02-10            2145
4       55519      offer          NULL                2020-05-09            4337
5       55519      order          NULL                2020-05-09            4018
6       55519      stock_in       delivered           2020-05-12            4018
6       55519      stock_in       completed           2020-07-08            3989

Основное отличие от оригинальных данных заключается в том, что столбцы date и quanttiy переключаются на строки и что в качестве столбца добавляется sub_event_type. sub_event_type добавляется, как только cID имеет event_type stock_in и

delivered_time IS NOT NULL = delivered
complete_time IS NOT NULL = completed

. Чтобы достичь этого, я выбрал решение из this вопрос:

 SELECT
  id,
  cID,
  event_type, 
  'delivered' AS sub_event_type, 
  delivered_time AS event_date,
  order_quantity AS quantity
  FROM PDW_FCT_Logistics
  WHERE event_type = 'stock_in' AND delivered_time IS NOT NULL

UNION ALL

  SELECT
  id,
  cID,
  event_type,
  'completed' AS sub_event_type,
  complete_time AS event_date,
  received as quantity
  FROM PDW_FCT_Logistics
  WHERE event_type = 'stock_in' AND complete_time IS NOT NULL

UNION ALL

  SELECT
  id,
  cID,
  event_type, 
  NULL AS sub_event_type,
  delivery_estimate AS event_date,
  plan_offer_quantity AS quantity
  FROM PDW_FCT_Logistics
  WHERE event_type = 'offer' 

UNION ALL

  SELECT
  id,
  cID,
  event_type, NULL AS sub_event_type,
  delivery_estimate AS event_date,
  order_quantity AS quantity
  FROM PDW_FCT_Logistics
  WHERE event_type = 'order'

ORDER BY 1;

Это почти дает мне нужный мне результат. Однако проблема заключается в том, что для cID 46902 в event_type stock_in нет quantity. В этом случае я хочу, чтобы quantity из event_type order использовался для sub_event_type delivered.

Что мне нужно изменить в моем запросе, чтобы эта работа работала?

1 Ответ

2 голосов
/ 11 марта 2020

Одним из вариантов будет использование коррелированного суб-выбора в части delivery вашего запроса. В этом случае он повторно запрашивает исходные данные, чтобы найти количество, связанное с событием order того же cID.

 SELECT
  id,
  cID,
  event_type, 
  'delivered' AS sub_event_type, 
  delivered_time AS event_date,
  CASE WHEN order_quantity IS NOT NULL THEN order_quantity --<--Edit starts here
       ELSE (SELECT order_quantity 
             FROM PDW_FCT_Logistics AS ss
             WHERE ss.cID = PDW_FCT_Logistics.cID
             AND ss.event_type = 'order')
  END AS quantity                                          --<--and ends here.
  FROM PDW_FCT_Logistics
  WHERE event_type = 'stock_in' AND delivered_time IS NOT NULL

UNION ALL

  SELECT
  id,
  cID,
  event_type,
  'completed' AS sub_event_type,
  complete_time AS event_date,
  received as quantity
  FROM PDW_FCT_Logistics
  WHERE event_type = 'stock_in' AND complete_time IS NOT NULL

UNION ALL

  SELECT
  id,
  cID,
  event_type, 
  NULL AS sub_event_type,
  delivery_estimate AS event_date,
  plan_offer_quantity AS quantity
  FROM PDW_FCT_Logistics
  WHERE event_type = 'offer' 

UNION ALL

  SELECT
  id,
  cID,
  event_type, NULL AS sub_event_type,
  delivery_estimate AS event_date,
  order_quantity AS quantity
  FROM PDW_FCT_Logistics
  WHERE event_type = 'order'

ORDER BY id;

Я также изменил предложение ORDER BY. Использование порядковых номеров столбцов нормально для ad ho c запросов, но в производственном коде этого следует избегать. См. Вредные привычки к удару: ORDER BY ordinal для получения более подробной информации.

Вот код, который работает в вашем DBFiddle . (И спасибо, что настроили это!

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