I am trying to select one row from multiple tables based on parameters, but my limited knowledge of SQL joining is holding me back. Could somebody possibly point me in the right direction?
Consider these table structures:
+-----------------------+ +---------------------+
| Customers | | Sellers |
+-------------+---------+ +-----------+---------+
| Customer_ID | Warning | | Seller_ID | Warning |
+-------------+---------+ +-----------+---------+
| 00001 | Test 1 | | 00008 | Testing |
| 00002 | Test 2 | | 00010 | Testing |
+-------------+---------+ +-----------+---------+
What I would like to do is one SELECT
to retrieve only one row, and in this row will be the 'Warning' field for each of the tables based on the X_ID field.
So, if I submitted the following information, I would receive the following results:
Example 1:
Customer_ID = 00001
Seller_ID = 00008
Results:
+-----------------------------------+
| Customer_Warning | Seller_Warning |
+------------------+----------------+
| Test 1 | Testing |
+------------------+----------------+
Example 2:
Customer_ID = 00001
Seller_ID = 00200
Results:
+-----------------------------------+
| Customer_Warning | Seller_Warning |
+------------------+----------------+
| Test 1 | NULL |
+------------------+----------------+
This is my current code (I am receiving loads of rows):
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
But I have also played around with UNION
, UNION ALL
and JOIN
. Which method should I go for?
Since you're not really joining tables together, just selecting a single row from each, you could do this:
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
The problem is you're getting a cartesian product of rows in each table where either column has the value you're looking for.
I think you just want AND
instead of 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
If performance isn't good enough you could join two filtered subqueries:
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
But I suspect SQL will be able to optimize the filtered join just fine.
it wont return a row if one of the ID's doesnt exist.
Then you want a 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
The problem that you are facing is that when one of the tables has no rows, you are going to get no rows out.
I would suggest solving this with a 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;
Also, I strongly discourage you from using single quotes for column aliases. Use single quotes only for string and date constants. Using them for column names can lead to confusion. In this case, you don't need delimiters on the names at all.
What I have seen so far here are working examples for your scenario. However, there is no real sense behind putting unrelated data together in one row. I would propose using a UNION
and separate the values in your code:
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
You can use the flag to distinguish the warnings in your code. This will be more efficient then joining or sub queries and will be easy to understand later on (when refactoring). I know this is not 100% what you ask for in your question but that's why I challenge the question :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.