此OR加入需要时间。我需要避免这种加入请建议。
Select * from [A] a
LEFT JOIN [B] b
ON A.ID = b.ID OR a.ID = b.ID_REF
答案 0 :(得分:2)
您的查询可以使用UNION
重新编写。你得到第一个条件的结果,然后是第二个条件的结果,然后合并两个。
SELECT * FROM [A] a LEFT JOIN [B] b ON a.ID = b.ID
UNION
SELECT * FROM [A] a LEFT JOIN [B] b ON a.ID = b.ID_REF;
然而,由于消除重复的任务,这可能比原始查询慢。
如果没有重复项(即b.ID
永远不等于b.ID_REF
),或者您只是不在乎是否得到了重复项,那么您可以使用UNION ALL
代替。这只是粘合两个结果而不删除重复项,因此这实际上可能比您的查询更快。您应该在A(ID)
,B(ID)
和B(ID_REF)
上建立索引。
SELECT * FROM [A] a LEFT JOIN [B] b ON a.ID = b.ID
UNION ALL
SELECT * FROM [A] a LEFT JOIN [B] b ON a.ID = b.ID_REF;
答案 1 :(得分:0)
如果没有关于您的表格,索引等的任何信息,这自然会是一个不完整的答案。在警告过你之后,我会说你可以想象将它分成两个独立的JOIN
条件,然后改变你的WHERE
条款以反映ID
字段的重要性/相关性,像这样:
SELECT *
FROM TableA A
LEFT JOIN TableB B1
ON A.ID = B1.ID
LEFT JOIN TableB B2
ON A.ID = B2.ID_REF
WHERE COALESCE(B1.ID,B2.ID_REF) = A.ID
;
当然,这有可能返回重复行的缺点,甚至可能比原始查询工作更慢,这取决于您的索引/键 - 但如上所述,我们将很难给出一个关于您正在使用的架构的信息很少,这是一个很好的答案。
只需使用一些超简单的虚拟数据来向您展示其工作原理:
DECLARE @TABLEA TABLE
(
ID INT
);
DECLARE @TABLEB TABLE
(
ID INT
,ID_REF INT
);
INSERT INTO @TABLEA
SELECT 1
UNION ALL
SELECT 2
UNION ALL
SELECT 3
UNION ALL
SELECT 4
UNION ALL
SELECT 5
UNION ALL
SELECT 6
;
INSERT INTO @TABLEB (ID, ID_REF)
SELECT 1,NULL
UNION ALL
SELECT NULL,2
UNION ALL
SELECT 3,3
UNION ALL
SELECT 4,NULL
UNION ALL
SELECT NULL,5
UNION ALL
SELECT 6,NULL
;
SELECT
A.ID AS [A_ID]
,COALESCE(B1.ID,B2.ID_Ref) AS [B_Final_ID]
FROM @TABLEA A
LEFT JOIN @TABLEB B1
ON A.ID = B1.ID
LEFT JOIN @TABLEB B2
ON A.ID = B2.ID_REF
WHERE COALESCE(B1.ID,B2.ID_REF) = A.ID
;
返回:
A_ID | B_Final_ID
-----+-----------
1 | 1
2 | 2
3 | 3
4 | 4
5 | 5
6 | 6
我会认真地建议您考虑提供一些虚拟数据,除了表格结构之外,这些数据不会对您的实际数据库产生任何影响。在我看来,这是你能够获得更好答案的唯一方式。