sql-server - 避免 MSSQL 中的多个左连接
问题描述
我有以下数据库结构:
Users
----------------------
| User_ID | Username |
|--------------------|
| 14590 | Sam |
| 14591 | Michael |
| 14592 | Albert |
----------------------
Addresses
----------------------------------------------
| Adr_ID | City | Street |
|--------------------------------------------|
| 62 | New York | Perfect Street 1 |
| 63 | New York | Another Street 12 |
| 64 | Prague | Zlata Ulicka 52 |
| 65 | Berlin | Alexanderplatz 36 |
| 66 | Berlin | Am Bahnhof 49 |
| 67 | Warsaw | Poniatowskiego 74 |
| 68 | Paris | Rue Des Barres 33 |
| 69 | Paris | Rue De L’abreuvoir 63 |
| 70 | Lisbon | Rua Augusta |
----------------------------------------------
Addresses_Link
------------------------------------------------------------
| Link_ID | Adr_ID | User_ID | Main_Address | Address_Type |
|----------------------------------------------------------|
| 570 | 62 | 14590 | 1 | 1 |
| 571 | 63 | 14590 | 1 | 2 |
| 572 | 64 | 14590 | 0 | 3 |
| 573 | 65 | 14591 | 1 | 1 |
| 574 | 66 | 14591 | 1 | 2 |
| 575 | 67 | 14591 | 0 | 3 |
| 576 | 68 | 14592 | 1 | 1 |
| 577 | 69 | 14592 | 1 | 2 |
| 578 | 70 | 14592 | 0 | 3 |
------------------------------------------------------------
我想得到的结果:
-----------------------------------------------------------------------------------------------------
| User_ID | Username | Adr_Private_City | Adr_Private_Street | Adr_Job_City | Adr_Job_Street |
|---------------------------------------------------------------------------------------------------|
| 14590 | Sam | New York | Perfect Street 1 | New York | Another Street 12 |
| 14591 | Michael | Berlin | Alexanderplatz 36 | Berlin | Am Bahnhof 49 |
| 14592 | Albert | Paris | Rue Des Barres 33 | Paris | Rue De L’abreuvoir 63 |
-----------------------------------------------------------------------------------------------------
列:
Adr_Private_City / Adr_Private_Street - 当 Main_Address = 1 和 Address_Type = 1 时
Adr_Job_City / Adr_Job_Street - 当 Main_Address = 1 和 Address_Type = 2
我创建了一个这样的 SQL 查询:
SELECT
u.User_ID,
u.Username,
a1.City AS Adr_Private_City,
a1.Street AS Adr_Private_Street,
a2.City AS Adr_Job_City,
a2.Street AS Adr_Job_Street
FROM Users u
LEFT JOIN Addresses_Link al1 ON al1.User_ID = u.User_ID
LEFT JOIN Addresses_Link al2 ON al2.User_ID = u.User_ID
LEFT JOIN Addresses a1 ON a1.Adr_ID = al1.Adr_ID
LEFT JOIN Addresses a2 ON a2.Adr_ID = al2.Adr_ID
WHERE
al1.Main_Address = 1 AND al1.Address_Type = 1 AND
al2.Main_Address = 1 AND al2.Address_Type = 2
是否可以避免多个左连接并使查询不会太慢?
解决方案
您可以通过以下方式实现您想要的
您的原始查询
FROM Users u
LEFT JOIN Addresses_Link al1 ON al1.User_ID = u.User_ID
....
WHERE al1.Main_Address = 1
当您在子句INNER JOIN
中有条件时,实际上是一个al1.Main_Address = 1
WHERE
既然你用过LEFT JOIN
,我就把它变成了一个真正的LEFT JOIN
查询。因为Addresses_Link
and Addresses
,既然你加入了Adr_ID
,我用INNER JOIN
SELECT *
FROM Users u
LEFT JOIN
(
SELECT al.User_ID,
MAX(CASE WHEN al.Address_Type = 1 THEN a.City END) AS Adr_Private_City,
MAX(CASE WHEN al.Address_Type = 1 THEN a.Street END) AS Adr_Private_Street,
MAX(CASE WHEN al.Address_Type = 2 THEN a.City END) AS Adr_Job_City,
MAX(CASE WHEN al.Address_Type = 2 THEN a.Street END) AS Adr_Job_Street,
FROM Addresses_Link al
INNER JOIN Addresses a ON a.Adr_ID = al.Adr_ID
WHERE al.Main_Address = 1
AND al.Address_Type IN (1, 2)
GROUP BY al.User_ID
) a ON a.User_ID = u.User_ID
推荐阅读
- javascript - ValidationError:无效的配置对象。Webpack 已使用与 API 模式不匹配的配置对象进行初始化。Next.js
- javascript - 使用按钮 js 功能显示/隐藏 DIV
- c# - 在 C# 中删除 Json 属性中的空格
- javascript - 引导轮播在wordpress的主页中不起作用
- python - 列表中的某些元素有分隔符,需要分隔。然后需要将该元素的其他值复制到新行。建议?
- netsuite - 通过传递给它的参数搜索预定的脚本实例
- javascript - 如何从 DOM 中删除数组的选定索引并反映 React 状态的变化?
- java - 使用 Java 和 Spark Eclipse 连接 Dataproc Hive 服务器时出现异常
- algorithm - 图 K11,12 中有多少条长度为 2 的路径?
- java - 在不使用 Java API 的情况下反转堆栈