2009-08-28 87 views
0

这是我的查询。我想要BF的所有行和匹配的FT行。它只返回2行,但实际行数为135.我应该如何更改我的查询?SQL Server中的外部连接问题

SELECT 
    BF.FaturaNo, 
    K.KlinikAdi, 
    FT.teslimAlindi, 
    FT.TeslimAciklama, 
    FT.kurumTeslimAldi, 
    FT.kurumTeslimAciklama, 
    BF.basilmisFatura_id, 
    K.klinik_id 
FROM 
    BasilmisFaturalar AS BF 
LEFT OUTER JOIN 
    FaturaTeslim AS FT 
    ON FT.refBasilmisFatura_id = BF.BasilmisFatura_id 
INNER JOIN 
    Klinikler AS K 
    ON BF.refKlinik_id = K.klinik_id 
INNER JOIN 
    Faturalar AS F 
    ON F.refBasilmisFatura_id = BF.basilmisFatura_id 
WHERE 
     BF.FaturaNo LIKE '%%' 
    AND BF.refklinik_id IN ('24','25','26','27') 
    AND MONTH(F.faturaTarihi) = 7 
    AND teslimAlindi = 0 
    AND kurumTeslimAldi = 0 
GROUP BY 
    F.refBasilmisFatura_id, 
    BF.FaturaNo, 
    K.KlinikAdi, 
    FT.teslimAlindi, 
    FT.TeslimAciklama, 
    FT.kurumTeslimAldi, 
    FT.kurumTeslimAciklama, 
    BF.basilmisFatura_id, 
    K.klinik_id 
ORDER BY 
    faturaNo ASC 

回答

-1

您的WHERE子句可能比您认为的要严格得多。试着拿出一些这些条款。

此外,BF.FaturaNo LIKE '%%'可能应该用更容易理解BF.FaturaNo IS NOT NULL

尝试减少你的问题的概念的一个简单的演示代替。你有太多的数据模型特定的东西内置到这个问题。

+0

拥有_BF.FaturaNo LIKE'%%'_与_BF.FaturaNo IS不是NULL_(我测试过)相同,这可能不是他们的意图,因为这个查询看起来像是动态构建的...我并不是投票!我同意你的看法,我认为他们需要逐个删除部分查询,并继续运行并查看结果,OP缺少一些东西。 – 2009-08-28 14:15:42

+0

感谢您的信息,我更改了我的回复以反映它。 – recursive 2009-08-28 14:17:29

+0

+1,我仍然认为欧普需要尝试减少查询 – 2009-08-28 14:37:51

2

您的teslimAlindi和kurumTeslimAldi过滤器位于“OUTER”侧,因此请将此BF加入INNER JOIN。

在加入或过滤ON子句之前,您需要先过滤。我更喜欢这种派生表方法

.... 
FROM BasilmisFaturalar AS BF 
    LEFT OUTER JOIN 
    (SELECT * 
    FROM 
     FaturaTeslim 
    WHERE 
     teslimAlindi = 0 AND 
     kurumTeslimAldi = 0 
    ) AS FT ON FT.refBasilmisFatura_id = BF.BasilmisFatura_id 
    INNER JOIN Klinikler AS K ON BF.refKlinik_id = K.klinik_id 
    INNER JOIN Faturalar AS F ON F.refBasilmisFatura_id = BF.basilmisFatura_id 
WHERE BF.FaturaNo LIKE '%%' AND 
    BF.refklinik_id IN ('24','25','26','27') AND 
    MONTH(F.faturaTarihi) = 7 
+0

相同的计数2 :( – cagin 2009-08-28 14:06:11

+1

你怎么知道真正的行数是135? – gbn 2009-08-28 14:15:40

2

你在你的where子句中有teslimAllindi和kurumTeslimAldi。

连接在where子句之前执行。因此,对于没有FakturaTeslim记录的每一行,TeslimAllindi和KurumTeslimAldi在加入后都将为NULL。

这些行将被where子句过滤掉,有效地使左连接作为内连接工作。

而应该这样写:

SELECT 
    BF.FaturaNo, 
    K.KlinikAdi, 
    FT.teslimAlindi, 
    FT.TeslimAciklama, 
    FT.kurumTeslimAldi, 
    FT.kurumTeslimAciklama, 
    BF.basilmisFatura_id, 
    K.klinik_id 
FROM 
    BasilmisFaturalar AS BF 
LEFT OUTER JOIN 
    FaturaTeslim AS FT 
    ON 
    (FT.refBasilmisFatura_id = BF.BasilmisFatura_id 
    AND teslimAlindi = 0 
    AND kurumTeslimAldi = 0) 
INNER JOIN 
    Klinikler AS K 
    ON BF.refKlinik_id = K.klinik_id 
INNER JOIN 
    Faturalar AS F 
    ON F.refBasilmisFatura_id = BF.basilmisFatura_id 
WHERE 
     BF.FaturaNo LIKE '%%' 
    AND BF.refklinik_id IN ('24','25','26','27') 
    AND MONTH(F.faturaTarihi) = 7 
GROUP BY 
    F.refBasilmisFatura_id, 
    BF.FaturaNo, 
    K.KlinikAdi, 
    FT.teslimAlindi, 
    FT.TeslimAciklama, 
    FT.kurumTeslimAldi, 
    FT.kurumTeslimAciklama, 
    BF.basilmisFatura_id, 
    K.klinik_id 
ORDER BY 
    faturaNo ASC 
2

的WHERE子句

AND teslimAlindi = 0 
AND kurumTeslimAldi = 0 

假设那些混叠的列从表FaturaTeslim,你所说的实际上是:
- 获取所有所需来自BasilmisFaturalar的行
- 将它们与FaturaTeslim中找到的任何行进行匹配,但如果没有找到,则可以使用
- 这些结果,折腾了所有行teslimAlindi <> 0 kurumTeslimAldi <> 0

与左外连接,对于没有匹配是在FaturaTeslim,teslimAlindi和kurumTeslimAldi发现那些行将是NULL ,并通过where子句去除它们(因为它们不是= 0)。

gbn的代码片段展示了如何通过检查外连接的ON子句中的那些值来解决这个问题 - 哪些工作在IF中,这是您希望实现的业务逻辑(即,仅LOJ那些teslimAlindi = 0和kurumTeslimAldi = 0

+0

好的解释 – HLGEM 2009-08-28 14:23:15

+0

把我的第三个项目符号点从“和”更改为“... <> 0或kurum ...“ – 2009-08-28 14:28:49