使用 OR 和标签连接多个列上的两个表
Posted
技术标签:
【中文标题】使用 OR 和标签连接多个列上的两个表【英文标题】:Join two tables on multiple columns with OR and label 【发布时间】:2021-12-26 14:24:52 【问题描述】:我有两个表,如下所示:
orderID | customerID |
---|---|
1 | 1001 |
2 | 1002 |
3 | 1003 |
4 | 1003 |
另一个是这样的:
userID | Service1FirstOrderID | Serice2FirstOrderID | Service3FirstOrderID |
---|---|---|---|
1001 | null | 1 | null |
1002 | 2 | null | null |
1003 | 3 | null | 4 |
现在我想加入这两个表,以便我可以获取每个已购买的带有ServiceID
的客户 ID。
UserID | Service |
---|---|
1001 | 2 |
1002 | 1 |
1003 | 1 |
1003 | 3 |
任何帮助将不胜感激。
【问题讨论】:
您真正使用的是哪个 DBMS? mysql (x) 还是 MySQL?只标记您真正使用的那个,仅此而已。 Edit 这样做的问题。 你是对的。我正在使用 SQL Server Edit 问题并解释结果背后的逻辑。 看起来这根本不是一个连接。它似乎纯粹是第二个表的条件逆透视,您可以使用CROSS APPLY (SELECT 1 WHERE Service1FirstOrderID IS NOT NULL UNION ALL SELECT 2 WHERE Service2FirstOrderID IS NOT NULL...
执行此操作,例如dbfiddle.uk/…。虽然为什么你首先有一个如此糟糕的非规范化结构是一个不同的问题
这行不通,因为还有一些其他列和条件已应用于第一个表,我应该计算 customerID,所以我必须加入这两个表,以便我可以计算客户每个服务
【参考方案1】:
可以加入IN
SELECT so.userID , CASE WHEN o.OrderID = so.Service1FirstOrderID THEN 1 WHEN o.OrderID = so.Service2FirstOrderID THEN 2 WHEN o.OrderID = so.Service3FirstOrderID THEN 3 END AS Service FROM Orders o INNER JOIN ServiceOrders so ON so.userID = o.customerID AND o.OrderID IN (so.Service1FirstOrderID, so.Service2FirstOrderID, so.Service3FirstOrderID) ORDER BY o.customerID;
userID | Service |
---|---|
1001 | 2 |
1002 | 1 |
1003 | 1 |
1003 | 3 |
dbfiddle here
上的演示【讨论】:
【参考方案2】:您有一个高度非规范化的表结构,但看起来这根本不是一个连接。
这似乎纯粹是第二个表的条件逆透视,您可以使用CROSS APPLY
来完成
SELECT
t2.UserId,
v.*
FROM table2 t2
CROSS APPLY (
SELECT 1
WHERE Service1FirstOrderID IS NOT NULL
UNION ALL
SELECT 2
WHERE Service2FirstOrderID IS NOT NULL
UNION ALL
SELECT 3
WHERE Service3FirstOrderID IS NOT NULL
) v(Service);
db<>fiddle
【讨论】:
【参考方案3】:您可以使用 CTE 实现此目的。
;WITH CTE_ServiceOrder as
(
SELECT UserId, 1 AS ServiceId, Service1FirstOrderID as orderId
from ServiceOrders
where Service1FirstOrderId is not null
union all
SELECT UserId, 2, Service2FirstOrderID as orderId
from ServiceOrders
where Service2FirstOrderId is not null
union all
SELECT UserId, 3, Service3FirstOrderID as orderId
from ServiceOrders
where Service3FirstOrderId is not null
)
SELECT o.customerID, s.ServiceId FROM CTE_ServiceOrder as s
INNER JOIN Orders as o
on o.orderID = s.orderid
order by o.customerID
感谢@Lukstorms 创建脚本。
您可以参考dbfiddle
【讨论】:
以上是关于使用 OR 和标签连接多个列上的两个表的主要内容,如果未能解决你的问题,请参考以下文章
非聚集索引 - 几乎相同需求的一个或两个索引(两个表之间的连接)?