SQL-左联接后丢失列
以下是我在DB Fiddle中的内容(使用PostgreSQL v9.6): 示例表: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
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*
的解决方案要好得多,因为这样可以避免歧义。