【发布时间】:2022-01-27 21:28:27
【问题描述】:
架构:
CREATE TABLE PRODUCT
(
PRODUCTID INT,
PRODUCTNAME VARCHAR(100),
PRODUCTUSER VARCHAR(100)
);
CREATE TABLE USER
(
USERID INT,
USERNAME VARCHAR(100),
USEREMAIL VARCHAR(100)
);
INSERT INTO PRODUCT(PRODUCTID,PRODUCTNAME,PRODUCTUSER)
VALUES (1, 'Product1', 'Chen'), (2, 'Product2', 'Bob'),
(3, 'Product3', ''), (4, 'Product4', '');
INSERT INTO USER (USERID, USERNAME, USEREMAIL)
VALUES (1, 'Chen', 'chen@email.com'),
(2, 'Bob', 'bob@email.com'),
(3, 'Paul', 'paul@email.com'),
(4, '', ''), (5, '', '');
产品表:
ProductID ProductName ProductUser
------------------------------------
1 Product1 Chen
2 Product2 Bob
3 Product3
4 Product4
用户表:
UserID UserName UserEmail
--------------------------------
1 Chen chen@email.com
2 Bob bob@email.com
3 Paul paul@email.com
4
5
我想加入产品和用户表以获取所有产品名称和用户名(如果可用)作为输出。挑战在于公共字段 Product.ProductUser 和 User.UserName 都包含空值,如上例所示。我知道这不是一个好的架构设计,但我无法更改架构,因为它超出了我的控制范围。
预期输出:
PROCUTNAME USERNAME
----------------------
Product1 Chen
Product2 Bob
Product3
Product4
示例查询 1:
SELECT PRODUCTNAME, USERNAME
FROM PRODUCT P
JOIN USER U
ON P.PRODUCTUSER=U.USERNAME
上面的查询是一个内部连接,因此返回 Product3 和 Product4 的重复项,因为连接为空。添加 WHERE 子句 ProductUser'' 会导致排除 Product3 和 Product4。
通常,如果 ProductUser 为 NULL 而不是空,那么我知道 LEFT JOIN 将是解决方案。我想我理解在 LEFT JOIN 的 ON 子句和 WHERE 子句中使用条件的区别。
因此尝试在 ON 子句中使用条件进行左连接:
SELECT PRODUCTNAME, USERNAME
FROM PRODUCT P
LEFT JOIN USER U
ON P.PRODUCTUSER=U.USERNAME AND P.PRODUCTUSER<>''
因此,上述查询首先根据 ON 子句中的给定条件进行内部连接,然后从产品表中提取所有其他行并将用户名设置为空。 (或者换句话说,它首先列出所有产品,然后加入那些满足 ON 标准的记录。)
这给了我预期的输出。但我不确定我的方法是否正确,所以尝试另一种方法:
SELECT PRODUCTNAME, USERNAME
FROM PRODUCT P
LEFT JOIN (SELECT * FROM USER WHERE USERNAME<>'') U
ON P.PRODUCTUSER=U.USERNAME
这也有效。
在 ON 子句中使用条件左连接是解决问题的正确方法吗?
【问题讨论】:
-
这两个查询之间的区别完全没有。它们将产生相同的查询计划。无论您做什么,都不要将
WHERE放在外部WHERE中,只能放在ON或内部WHERE中。他们是''还是NULL? -
你为什么不能只做
SELECT PRODUCTNAME, USERNAME FROM PRODUCT?它准确地返回您请求的预期输出.. -
用户表中还有几个我还想要的值
标签: sql sql-server tsql