在SQL中使用左连接而不是子查询

时间:2013-12-30 21:15:06

标签: sql join

我被告知我可以使用左连接而不是下面的子查询,任何人都可以帮助我理解如何...谢谢。

我需要获取过去5年内未见过的设备序列号。此数据跨两个不同的数据库,而序列号位于第三个数据库中。如果您有其他指示来帮助运行此查询更顺畅,我欢迎他们。

这是为HeadEnd文件中的帐户寻找Workorders,而不是在快照中,并且在5年内没有看到(要在db-prod上运行)。

use vcr6_prod
go 

select * from [GC-DEV-TEST\TEST2008R2].TeriResearch.dbo.comedheadend20131216
where Serial in (
select 
--sa.ObservedComplete,
--pwo.wo_completedate,
----wod.d_ID,
----wod.wo_id,
--pwo.wo_id,
--woi.UserList0,
--wo.userdata0
--distinct 
cehe.serial 
--*
from
[GC-DEV-TEST\TEST2008R2].TeriResearch.dbo.comedheadend20131216 cehe
join [GC-DEV-TEST\TEST2008R2].TeriResearch.dbo.ComEd120131115 ce
                               on cehe.premise_desc = ce.PremiseNbr

join OutReach25.dbo.Premise p on p.PremiseDesc = cehe.premise_desc

join OutReach25.dbo.CustomerPremise cp on cp.PremiseID = p.PremiseID 
left join [vcr6_prod].dbo.workorder wo 
                                       on convert (varchar, cp.premiseid) = wo.account 
join VCR6_PROD.dbo.WorkOrderItem woi on woi.WorkOrder = wo.workorder 
                                            and woi.Serial = cehe.serial 
left join [colo-db1].ComedNF_IL.dbo.p_workorder pwo
                                           on wo.userdata0 = pwo.wo_number 
left join ScheduleAssignment sa 
                                           on wo.WorkOrder = sa.WorkOrderId 

where wo.BranchId = 'comed'
and cp.ProjectID = 55

and       (    
             pwo.wo_completedate < DateAdd(yy, -5, GetDate())
             or 
             (
                   sa.ObservedComplete < DateAdd(yy, -5, GetDate()) 
                   and
                   sa.ObservedComplete <> '1990-01-01 00:00:00.000'
              )
          ))
      and Serial not in
      (
select 
--sa.ObservedComplete,
--pwo.wo_completedate,
----wod.d_ID,
----wod.wo_id,
--pwo.wo_id,
--woi.UserList0,
--wo.userdata0
--distinct 
cehe.serial 
--*
from
[GC-DEV-TEST\TEST2008R2].TeriResearch.dbo.comedheadend20131216 cehe
join [GC-DEV-TEST\TEST2008R2].TeriResearch.dbo.ComEd120131115 ce
                               on cehe.premise_desc = ce.PremiseNbr

join OutReach25.dbo.Premise p on p.PremiseDesc = cehe.premise_desc

join OutReach25.dbo.CustomerPremise cp on cp.PremiseID = p.PremiseID 
left join [vcr6_prod].dbo.workorder wo 
                                       on convert (varchar, cp.premiseid) = wo.account 
join VCR6_PROD.dbo.WorkOrderItem woi on woi.WorkOrder = wo.workorder 
                                            and woi.Serial = cehe.serial 
left join [colo-db1].ComedNF_IL.dbo.p_workorder pwo
                                           on wo.userdata0 = pwo.wo_number 
left join ScheduleAssignment sa 
                                           on wo.WorkOrder = sa.WorkOrderId 

where wo.BranchId = 'comed'
and cp.ProjectID = 55

and       (    
             pwo.wo_completedate > DateAdd(yy, -5, GetDate())
             or 
             (
                   sa.ObservedComplete > DateAdd(yy, -5, GetDate()) 
                   and
                   sa.ObservedComplete <> '1990-01-01 00:00:00.000'
              )
          ))




--and sa.ObservedComplete is not null

2 个答案:

答案 0 :(得分:2)

使用LEFT JOIN模拟NOT IN:

SELECT table1.columns
FROM Table1 LEFT JOIN table2 ON table1.key = table2.key
WHERE table2.key is NULL

答案 1 :(得分:0)

您的查询

select * from table_A 
where X in ( Select X From Table_C 
             where column_1 is > 5) 
and where X not in ( Select X From Table_C 
                    where column_1 is < 5)

现在,如果您仔细观察,如果检查相同的条件,则两个条件都是where子句。

测试数据

现在在联接的帮助下实现相同的输出,见下文

DECLARE @Table_A TABLE (X INT, Column_1 INT)
INSERT INTO @Table_A 
VALUES 
(1, 100),(2, 200),(3, 300),
(4, 400),(5, 500),(6, 600),
(7, 700),(8, 800),(9, 900)

DECLARE @Table_C TABLE (X INT, Column_1 INT)
INSERT INTO @Table_C 
VALUES 
(1, 100),(2, 200),(3, 300),
(4, 400),(5, 500),(6, 600),
(7, 700),(8, 800),(9, 900)

<强>查询

我建议加入并且只检查一个条件,你提到了你的where子句。

SELECT A.*
FROM @Table_A A INNER JOIN @Table_C C
ON A.X = C.X
WHERE C.Column_1 > 500

使用联接检查查询中提到的两个条件。

SELECT A.*
FROM @Table_A A INNER JOIN @Table_C C
ON A.X = C.X
INNER JOIN @Table_C D
ON A.X = D.X
WHERE C.Column_1 > 500
AND D.Column_1 !< 500

但两个查询都会返回完全相同的结果。如下

结果设置

╔═══╦══════════╗
║ X ║ Column_1 ║
╠═══╬══════════╣
║ 6 ║      600 ║
║ 7 ║      700 ║
║ 8 ║      800 ║
║ 9 ║      900 ║
╚═══╩══════════╝

我认为您不需要检查where子句中的两个条件。由于两种情况在逻辑上是相同的。

就像我说的那样I am not a TeenagerI am not Less then 20 years old :)