簡體   English   中英

來自多個表的UNION或JOIN for SELECT

[英]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

但我也玩過UNIONUNION ALLJOIN 我應該選擇哪種方法?

由於您並未真正將表連接在一起,只需從每個表中選擇一行,您可以這樣做:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM