[英]UNION or JOIN for SELECT from multiple tables
我试图根据参数从多个表中选择一行,但我对SQL加入的有限知识阻碍了我。 有人可能会指出我正确的方向吗?
考虑这些表结构:
+-----------------------+ +---------------------+
| Customers | | Sellers |
+-------------+---------+ +-----------+---------+
| Customer_ID | Warning | | Seller_ID | Warning |
+-------------+---------+ +-----------+---------+
| 00001 | Test 1 | | 00008 | Testing |
| 00002 | Test 2 | | 00010 | Testing |
+-------------+---------+ +-----------+---------+
我想要做的是一个SELECT
只检索一行,在这一行中将是基于X_ID字段的每个表的'Warning'字段。
所以,如果我提交了以下信息,我会收到以下结果:
例1:
Customer_ID = 00001
Seller_ID = 00008
Results:
+-----------------------------------+
| Customer_Warning | Seller_Warning |
+------------------+----------------+
| Test 1 | Testing |
+------------------+----------------+
例2:
Customer_ID = 00001
Seller_ID = 00200
Results:
+-----------------------------------+
| Customer_Warning | Seller_Warning |
+------------------+----------------+
| Test 1 | NULL |
+------------------+----------------+
这是我当前的代码(我收到了大量的行):
SELECT c.Warning 'Customer_Warning', s.Warning AS 'Seller_Warning'
FROM Customers c,Sellers s
WHERE c.Customer_ID = @Customer_ID
OR s.Seller_ID = @Seller_ID
但我也玩过UNION
, UNION ALL
和JOIN
。 我应该选择哪种方法?
由于您并未真正将表连接在一起,只需从每个表中选择一行,您可以这样做:
SELECT
(SELECT Warning
FROM Customers
WHERE Customer_ID = @Customer_ID) AS Customer_Warning,
(SELECT Warning
FROM Sellers
WHERE Seller_ID = @Seller_ID) AS Seller_Warning
问题是你在每个表中得到行的笛卡尔积,其中任一列都有你正在寻找的值。
我想你只想要AND
而不是OR
:
SELECT c.Warning 'Customer_Warning', s.Warning AS 'Seller_Warning'
FROM Customers c
JOIN Sellers s
ON c.Customer_ID = @Customer_ID
AND s.Seller_ID = @Seller_ID
如果性能不够好,您可以加入两个过滤的子查询:
SELECT c.Warning 'Customer_Warning', s.Warning AS 'Seller_Warning'
FROM (SELECT Warnning FROM Customers WHERE c.Customer_ID = @Customer_ID) c,
(SELECT Warning FROM Sellers s WHERE s.Seller_ID = @Seller_ID) s
但我怀疑SQL能够优化过滤连接。
如果其中一个ID不存在,它就不会返回一行。
然后你想要一个FULL OUTER JOIN
:
SELECT c.Warning 'Customer_Warning', s.Warning AS 'Seller_Warning'
FROM Customers c
FULL OUTER JOIN Sellers s
ON c.Customer_ID = @Customer_ID
AND s.Seller_ID = @Seller_ID
您遇到的问题是,当其中一个表没有行时,您将不会输出任何行。
我建议用full outer join
解决这个问题:
SELECT c.Warning as Customer_Warning, s.Warning AS Seller_Warning
FROM Customers c FULL OUTER JOIN
Sellers s
ON c.Customer_ID = @Customer_ID AND s.Seller_ID = @Seller_ID;
另外,我强烈建议您不要使用单引号作为列别名。 仅对字符串和日期常量使用单引号。 将它们用于列名可能会导致混淆。 在这种情况下,您根本不需要对名称进行分隔。
到目前为止,我在这里看到的是您的场景的工作示例。 但是,将不相关的数据放在一行背后并没有真正的意义。 我建议使用UNION
并将代码中的值分开:
SELECT 'C' AS Type, c.Warning
FROM Customers c
WHERE c.Customer_ID = @Customer_ID
UNION
SELECT 'S' AS Type, s.Warning
FROM Sellers s
WHERE s.Seller_ID = @Seller_ID
您可以使用该标志来区分代码中的警告。 这将比加入或子查询更有效,并且稍后将很容易理解(重构时)。 我知道这不是你在问题中要求的100%,但这就是我挑战这个问题的原因:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.