简体   繁体   English

来自多个表的UNION或JOIN for SELECT

[英]UNION or JOIN for SELECT from multiple tables

My Issue 我的问题

I am trying to select one row from multiple tables based on parameters, but my limited knowledge of SQL joining is holding me back. 我试图根据参数从多个表中选择一行,但我对SQL加入的有限知识阻碍了我。 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. 我想要做的是一个SELECT只检索一行,在这一行中将是基于X_ID字段的每个表的'Warning'字段。

Desired Results 期望的结果

So, if I submitted the following information, I would receive the following results: 所以,如果我提交了以下信息,我会收到以下结果:

Example 1: 例1:

Customer_ID = 00001
Seller_ID = 00008

Results:
+-----------------------------------+
| Customer_Warning | Seller_Warning |
+------------------+----------------+
| Test 1           | Testing        |
+------------------+----------------+

Example 2: 例2:

Customer_ID = 00001
Seller_ID = 00200

Results:
+-----------------------------------+
| Customer_Warning | Seller_Warning |
+------------------+----------------+
| Test 1           | NULL           |
+------------------+----------------+

What I Have Tried 我曾经尝试过什么

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 . 但我也玩过UNIONUNION ALLJOIN 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 : 我想你只想要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

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. 但我怀疑SQL能够优化过滤连接。

it wont return a row if one of the ID's doesnt exist. 如果其中一个ID不存在,它就不会返回一行。

Then you want a FULL OUTER JOIN : 然后你想要一个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 : 我建议用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: 我建议使用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

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 :) 我知道这不是你在问题中要求的100%,但这就是我挑战这个问题的原因:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM