SQL - потеря столбцов после левого соединения - PullRequest
1 голос
/ 23 января 2020

Вот что у меня есть в DB Fiddle (используя PostgreSQL v9.6):

Пример таблицы:

CREATE TABLE sample_table (
  seller_id varchar(255),
  week varchar(255),
  week_end  timestamp,
  year  integer,
  product_id varchar(255),
  num_sold  integer,
  dollars_sold  integer
);

Заполнено поддельными данными:

INSERT INTO sample_table (seller_id, week, week_end, year, product_id, num_sold, dollars_sold)
VALUES ('12345A', '01/01/2020 - 01/07/2020', '01/07/2020', 2020, '1A', 1, 5),
       ('12345A', '01/08/2020 - 01/14/2020', '01/14/2020', 2020, '1A', 2, 10),
       ('12345A', '01/15/2020 - 01/21/2020', '01/21/2020', 2020, '1A', 3, 15),
       ('12345B', '01/01/2020 - 01/07/2020', '01/07/2020', 2020, '1A', 2, 10),
       ('12345B', '01/08/2020 - 01/14/2020', '01/14/2020', 2020, '1A', 4, 20),
       ('12345B', '01/15/2020 - 01/21/2020', '01/21/2020', 2020, '1A', 6, 30),
       ('12345C', '01/01/2020 - 01/07/2020', '01/07/2020', 2020, '1A', 1, 5),
       ('12345C', '01/08/2020 - 01/14/2020', '01/14/2020', 2020, '1A', 2, 10),
       ('12345C', '01/15/2020 - 01/21/2020', '01/21/2020', 2020, '1A', 3, 15),
       ('12345D', '01/01/2020 - 01/07/2020', '01/07/2020', 2020, '1A', 5, 25),
       ('12345D', '01/08/2020 - 01/14/2020', '01/14/2020', 2020, '1A', 10, 50),
       ('12345D', '01/15/2020 - 01/21/2020', '01/21/2020', 2020, '1A', 15, 75),
       ('12345E', '01/01/2020 - 01/07/2020', '01/07/2020', 2020, '1A', 3, 15),
       ('12345E', '01/08/2020 - 01/14/2020', '01/14/2020', 2020, '1A', 6, 30),
       ('12345E', '01/15/2020 - 01/21/2020', '01/21/2020', 2020, '1A', 9, 45);

И мой запрос:

SELECT a.* FROM (SELECT     x.week_end, 
           x.week, 
           x.year, 
           y.product_id, 
           z.seller_id 
FROM       ( 
                           SELECT DISTINCT week_end, 
                                           year, 
                                           week 
                           FROM            sample_table) x 
CROSS JOIN 
           ( 
                           SELECT DISTINCT product_id 
                           FROM            sample_table) y 
CROSS JOIN 
           ( 
                           SELECT DISTINCT seller_id 
                           FROM            sample_table) z) AS a
LEFT JOIN sample_table b
ON 
a.seller_id = b.seller_id
AND 
a.week_end = b.week_end 
AND 
a.product_id = b.product_id;

Вот что я ожидаю: запрос берет каждую существующую комбинацию week + week_end + year из таблицы, перекрестно соединяя ее с каждым существующий product_id, а затем перекрестные соединения, которые получаются с каждым существующим seller_id. В то время как в моей таблице примеров это не отражено, в реальной таблице, с которой я работаю, отсутствуют строки, и цель состоит в том, чтобы сгенерировать эти отсутствующие строки, создав каждую комбинацию уже существующих строк. Например, если у продавца 12345A отсутствовали данные за неделю с 01.01.2020 по 01.072020 для определенного товара, то после этой операции будет создана эта недостающая строка.

На выпуске : после перекрестного соединения я хочу снова присоединить таблицу обратно к себе, чтобы вернуть данные num_sold и dollars_sold для уже существующих строк (и любые сгенерированные пропущенные строки будут отображать ноль).

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

Ответы [ 2 ]

2 голосов
/ 23 января 2020

Вы создали a, чтобы получить все комбинации недели / товара / продавца. Просто выбор a.* не будет отображать никаких других данных , кроме недели / продукта / продавца. Вы пропустили включение этих полей (num_sold и dollar_sold) из левого соединения с псевдонимом b, поэтому в основном вам нужно добавить их в основной выбор, используя b псевдоним:

SELECT a.*, b.sum_sold, b.dollars_sold FROM 
 (SELECT     x.week_end, 
           x.week, 
           x.year, 
           y.product_id, 
           z.seller_id 
FROM       ( 
                           SELECT DISTINCT week_end, 
                                           year, 
                                           week 
                           FROM            sample_table) x 
CROSS JOIN 
           ( 
                           SELECT DISTINCT product_id 
                           FROM            sample_table) y 
CROSS JOIN 
           ( 
                           SELECT DISTINCT seller_id 
                           FROM            sample_table) z) AS a 
LEFT JOIN sample_table b ON 
a.seller_id = b.seller_id
AND 
a.week_end = b.week_end 
AND 
a.product_id = b.product_id;
0 голосов
/ 23 января 2020

Эти столбцы находятся на входе и в результате левого соединения. Они не в x, y, z или в результатах CROSS JOIN. Вы можете назвать их с или без псевдонима b. Но вы не выбираете их в своем крайнем предложении SELECT.

...