SQL-左联接后丢失列

SQL-左联接后丢失列,sql,postgresql,left-join,cross-join,Sql,Postgresql,Left Join,Cross Join,以下是我在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

以下是我在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;
以下是我期望发生的情况:查询从表中获取
+
+
的每个现有组合,将其与每个现有
产品id
交叉联接,然后将结果与每个现有
卖家id
交叉联接。虽然我的示例表没有反映这一点,但我使用的实际表缺少行,目标是通过创建已经存在的每一行组合来生成缺少的行。例如,如果卖家12345A在2020年1月1日至2020年7月1日这一周内丢失了某个产品的数据,则在此操作之后,将创建丢失的行

关于这个问题:在交叉连接之后,我想将表左连接回它自己,以便将已经存在的行的
num_selled
dollars_selled
数据返回(生成的任何缺少的行都将显示空值)


在我左键加入后,
num\u sell
dollars\u sell
列丢失,我感到困惑。我从另一个与此表非常相似的表中复制了查询,并简单地更改了一些列名称。我复制的查询的工作原理与前面所述完全相同,但是当我在这个新表上运行这个修改后的查询时,这两列并没有通过左连接。

这些列在输入中&左连接的结果。它们不在x、y、z或交叉连接结果中。您可以使用别名b或不使用别名b来命名它们。但您并没有在最外层的SELECT子句中选择它们

这些列在输入中&左连接的结果。它们不在x、y、z或交叉连接结果中。您可以使用别名b或不使用别名b来命名它们。但您并没有在最外层的SELECT子句中选择它们

您已经创建了
a
来获取周/产品/卖家的所有组合。仅选择
a.*
将不会显示除周/产品/卖家之外的任何其他数据。 您没有在别名为
b
的左侧连接中包含这些字段(num\u sell和dollars\u sell),因此基本上您需要使用
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;

您已经创建了
a
来获取周/产品/卖家的所有组合。仅选择
a.*
将不会显示除周/产品/卖家之外的任何其他数据。 您没有在别名为
b
的左侧连接中包含这些字段(num\u sell和dollars\u sell),因此基本上您需要使用
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;

了解LEFT JOIN ON returns(左联接返回):行的内部联接将所有不匹配的左表行合并为null扩展。始终知道作为外部联接的一部分,您需要什么样的内部联接。外部连接打开后,要求右[sic]表列不为NULL的WHERE或内部连接将删除由NULL扩展的任何行,即只保留行上的内部连接,即“将外部连接转换为内部连接”。你有。当你得到一个你不期望/不理解的结果时,停止寻找你的总体目标,找出你的误解是什么。--隔离第一个意外/误解的子表达式及其输入和输出,了解是什么误解、打字错误、错误推理等导致了它。(基本原理)问一下。当你给出一个你能给出的最少的代码时,那就是你所显示的代码是OK的,由你所显示的代码扩展为NotOK的代码。(调试基础。)@philipxy我知道问题出在哪里了。我已将最外层的select从
select a.*
更改为
select*
,现在所有列都通过了。我以前避免过这样做,因为这会在查询的其他地方导致歧义错误。了解返回时的左连接:行上的内部连接联合所有未匹配的左表行以null扩展。始终知道作为外部联接的一部分,您需要什么样的内部联接。外部连接打开后,要求右[sic]表列不为NULL的WHERE或内部连接将删除由NULL扩展的任何行,即只保留行上的内部连接,即“将外部连接转换为内部连接”。你有。当你得到一个你不期望/不理解的结果时,停止寻找你的总体目标,找出你的误解是什么。--隔离第一个意外/误解的子表达式及其输入和输出,了解是什么误解、打字错误、错误推理等导致了它。(基本原理)问一下。当你给出一个你能给出的最少的代码时,那就是你所显示的代码是OK的,由你所显示的代码扩展为NotOK的代码。(调试基础。)@philipxy我知道问题出在哪里了。我已将最外层的select从
select a.*
更改为
select*
,现在所有列都通过了。我以前避免过这样做,因为这会在我的查询中的其他地方造成歧义错误。这是我一直在寻找的答案,比我在最外层的选择中简单地执行
SELECT*
的解决方案要好得多,因为这样可以避免歧义。这是我一直在寻找的答案,而且比我在最外层的SELECT中简单地执行
SELECT*
的解决方案要好得多,因为这样可以避免歧义。