T-SQL连接/返回不同结果的位置

T-SQL连接/返回不同结果的位置,sql,sql-server,join,Sql,Sql Server,Join,我有一个查询,我正在尽可能地优化它,如果我可以使用一个连接而不是当前的连接(WHERE-IN),它将对我有很大帮助 目前,我的查询是: SELECT cus.* , com.COM_ID , cha.CHA_NAME FROM thing.dbo.VIEW_REPORT cus --View LEFT JOIN otherthing.dbo.TBL_COMMUNICATION com ON com.REC_ID = cus.REC_ID AND com.RUN_ID = cus.RUN_

我有一个查询,我正在尽可能地优化它,如果我可以使用一个连接而不是当前的连接(WHERE-IN),它将对我有很大帮助

目前,我的查询是:

SELECT  
cus.*
, com.COM_ID
, cha.CHA_NAME
FROM thing.dbo.VIEW_REPORT cus --View
LEFT JOIN otherthing.dbo.TBL_COMMUNICATION com 
ON com.REC_ID = cus.REC_ID 
AND com.RUN_ID = cus.RUN_ID 
LEFT JOIN otherthing.dbo.TBL_CHANNEL cha
ON cha.CHA_ID = com.CHA_ID 
WHERE com.COM_ID in (
    SELECT eve.COM_ID 
    FROM otherthing.dbo.TBL_EVENT eve)
我试图通过加入TBL_活动而不是WHERE IN来优化这一点(我相信我读到它们的运行方式是相同的,但我也想选择一些TBL_活动专栏,这样加入就好了)。我的新查询如下:

SELECT  
cus.*
, com.COM_ID
, cha.CHA_NAME
FROM thing.dbo.VIEW_REPORT cus --View
LEFT JOIN otherthing.dbo.TBL_COMMUNICATION com 
ON com.REC_ID = cus.REC_ID 
AND com.RUN_ID = cus.RUN_ID 
LEFT JOIN otherthing.dbo.TBL_CHANNEL cha
ON cha.CHA_ID = com.CHA_ID 
INNER JOIN otherthing.dbo.TBL_EVENT eve
ON com.COM_ID = eve.COM_ID 
我认为使用内部联接意味着它只返回TBL_通信和TBL_事件中的结果这就是事情变得奇怪的地方。

原始查询(顶部)返回约200000条记录。我的新查询返回大约1100000条记录。但从我的角度来看,他们是同一个问题,所以我不确定我做错了什么。我已经将内部连接移到了TBL_事件,而不是其他左连接,但这似乎没有什么区别

有谁能告诉我,我应该怎样做才能通过参加TBL_活动返回相同的数据

它们不一样

WHERE com.COM_ID in (
   SELECT eve.COM_ID 
   FROM otherthing.dbo.TBL_EVENT eve)
表示必须在子查询的结果中找到com.com_ID。但是

INNER JOIN otherthing.dbo.TBL_EVENT eve
   ON com.COM_ID = eve.COM_ID 
表示加入eve.COM_ID与COM.COM_ID相同的所有帖子


如果您在eve.COM\u ID中有多个帖子具有相同的COM\u ID,您将在结果中获得多个帖子。

这里没有什么奇怪的,当TBL\u事件中有多行与视图报告和TBL\u通信的一行连接匹配时,就会发生这种情况

您不能像第二个脚本那样进行优化以首先获得相同的结果

您可以像下面这样优化sql,而不是重用第一个sql,这将提高脚本的速度

SELECT  
cus.*
, com.COM_ID
, cha.CHA_NAME
FROM thing.dbo.VIEW_REPORT cus --View
LEFT JOIN otherthing.dbo.TBL_COMMUNICATION com 
ON com.REC_ID = cus.REC_ID 
AND com.RUN_ID = cus.RUN_ID 
and com.COM_ID in (
    SELECT distinct eve.COM_ID 
    FROM otherthing.dbo.TBL_EVENT eve)
LEFT JOIN otherthing.dbo.TBL_CHANNEL cha
ON cha.CHA_ID = com.CHA_ID 
INNER JOIN otherthing.dbo.TBL_EVENT eve
ON com.COM_ID = eve.COM_ID 


你们杀了左派,加入otherthing.dbo.TBL_通信com和where,这会给你们另一个答案。如果你更喜欢你的第一个答案,那么把它改成一个普通的连接

SELECT cus.*, com.COM_ID, cha.CHA_NAME
FROM thing.dbo.VIEW_REPORT cus --View
LEFT JOIN otherthing.dbo.TBL_COMMUNICATION com 
       ON com.REC_ID = cus.REC_ID 
      AND com.RUN_ID = cus.RUN_ID 
      AND exists ( SELECT 1 
                   FROM otherthing.dbo.TBL_EVENT eve 
                   where eve.COM_ID = com.COM_ID )
LEFT JOIN otherthing.dbo.TBL_CHANNEL cha
       ON cha.CHA_ID = com.CHA_ID 
但这个问题对我来说毫无意义。
为什么要限制左联接的右侧?
很确定你的意思是,这是一个内部连接

SELECT cus.*, com.COM_ID, cha.CHA_NAME
FROM thing.dbo.VIEW_REPORT cus --View
JOIN otherthing.dbo.TBL_COMMUNICATION com 
       ON com.REC_ID = cus.REC_ID 
      AND com.RUN_ID = cus.RUN_ID 
      AND exists ( SELECT 1 
                   FROM otherthing.dbo.TBL_EVENT eve 
                   where eve.COM_ID = com.COM_ID )
LEFT JOIN otherthing.dbo.TBL_CHANNEL cha
       ON cha.CHA_ID = com.CHA_ID 

发布查询计划

左连接
时,将右侧表的条件放在
ON
子句中,以获得真正的左连接行为。(在WHERE中,您将获得常规的内部联接结果。)如果在
表1
中有3条COM_ID为'Z'的记录,在
表2中有4条COM_ID为'Z'的记录,则结果将是3 x 4条记录=12条记录。COM_ID在两个表中都是唯一的吗?COM_ID在TBL_通信中是唯一的。我知道你在说什么,所以我现在只是在尝试选择一个不同的,理论上应该返回相同的金额。(也就是说,正确的数量)
SELECT DISTINCT
有其自身的性能问题。
在存在的地方
可能会执行得更好,但它不允许您从
TBL\u事件中返回列
TBL\u事件中有数亿条记录(以及数百万条TBL\u通信记录)所以我觉得加入会更好?
SELECT cus.*, com.COM_ID, cha.CHA_NAME
FROM thing.dbo.VIEW_REPORT cus --View
JOIN otherthing.dbo.TBL_COMMUNICATION com 
       ON com.REC_ID = cus.REC_ID 
      AND com.RUN_ID = cus.RUN_ID 
      AND exists ( SELECT 1 
                   FROM otherthing.dbo.TBL_EVENT eve 
                   where eve.COM_ID = com.COM_ID )
LEFT JOIN otherthing.dbo.TBL_CHANNEL cha
       ON cha.CHA_ID = com.CHA_ID