如何在不使用多个JOIN查询的情况下将1个表与另一个表中的多列链接? 以下是我的情况:
我有User
和ID
的表Name
User
+---------+------------+
| Id | Name |
+---------+------------+
| 1 | John |
| 2 | Mike |
| 3 | Charles |
+---------+------------+
表Product
有多列,但仅关注2列CreateBy
和ModifiedBy
+------------+-----------+-------------+
| product_id | CreateBy | ModifiedBy |
+------------+-----------+-------------+
| 1 | 1 | 3 |
| 2 | 1 | 3 |
| 3 | 2 | 3 |
| 4 | 2 | 1 |
| 5 | 2 | 3 |
+------------+-----------+-------------+
使用普通的JOIN
,我将需要进行2次JOIN:
SELECT p.Product_id,
u1.Name AS CreateByName,
u2.Name AS ModifiedByName
FROM Product p
JOIN USER user u1 ON p.CreateBy = u1.Id,
JOIN USER user u2 ON p.ModifiedBy = u2.Id
得出结果
+------------+---------------+-----------------+
| product_id | CreateByName | ModifiedByName |
+------------+---------------+-----------------+
| 1 | John | Charles |
| 2 | John | Charles |
| 3 | Mike | Charles |
| 4 | Mike | John |
| 5 | Mike | Charles |
+------------+---------------+-----------------+
如何避免两次JOIN
?
我正在使用MS-SQL,但出于自己的好奇心向所有SQL查询开放
答案 0 :(得分:1)
我认为您当前的设计/方法是可以接受的,并且需要两个联接是因为有两个用户ID列。两列中的每一列都需要一个单独的联接。
有趣的是,这是一个表设计,如果您真的只想执行一个联接,可以考虑使用它:
+------------+-----------+-------------+
| product_id | user_id | type |
+------------+-----------+-------------+
| 1 | 1 | created |
| 2 | 1 | created |
| 3 | 2 | created |
| 4 | 2 | created |
| 5 | 2 | created |
| 1 | 3 | modified |
| 2 | 3 | modified |
| 3 | 3 | modified |
| 4 | 1 | modified |
| 5 | 3 | modified |
+------------+-----------+-------------+
现在,您只需进行一个简单的联接,然后进行聚合:
SELECT
p.product_id,
MAX(CASE WHEN t.type = 'created' THEN u.Name END) AS CreateByName,
MAX(CASE WHEN t.type = 'modified' THEN u.Name END) AS ModifiedByName
FROM Product p
INNER JOIN user u
ON p.user_id = u.Id
GROUP BY
p.product_id;
请注意,我完全不推荐这种方法。使用当前的方法并使用两个联接要干净得多。使用一个或多个索引可以很容易地优化联接。上面的聚合方法可能无法达到您已有的效果。
答案 1 :(得分:1)
如果使用自然键而不是替代键,则完全不需要加入。 我不知道您如何将您的产品与现实世界区分开来,但是对于这个示例,我假设您拥有一个UPC
CREATE TABLE User
(Name VARCHAR(20) PRIMARY KEY);
CREATE TABLE Product
(UPC CHAR(12) PRIMARY KEY,
CreatedBy VARCHAR(20) REFERENCES User(Name),
ModifiedBy VARCHAR(20) REFERENCES User(Name)
);
现在,您的查询是一个简单的选择,并且您还将用户名的唯一性作为奖励,并且不需要其他索引。 试试吧...
HTH
答案 2 :(得分:1)
加入是最好的方法,但是如果要寻找替代方法,则可以使用内联查询。
SELECT P.PRODUCT_ID,
(SELECT [NAME] FROM @USER WHERE ID = CREATED_BY) AS CREATED_BY,
(SELECT [NAME] FROM @USER WHERE ID = MODIFIED_BY) AS MODIFIED_BY
FROM @PRODUCT P