SQL Server - 连接中缺少记录

时间:2013-05-18 14:01:36

标签: sql sql-server join rows

我正在尝试使用以下查询来完成以下操作:

  • 根据表格中包含的各种条件,从Dial表和组中获取所有记录
  • 将表格加入唯一密钥(HistoryDial.UID)上的History.UID表,以返回Dial
  • 无法获取的一些信息

一切正常,除了它没有从Dial表中返回UID为0的行(一旦处理了记录,这在两个表中都会更新,但如果没有处理后,它仍然是0)。我想将UID为0的所有记录的计数添加到Total Avail中。和Total Eligible列,基于Dial.ID

有人可以帮忙吗?

此致

SELECT 
    (CASE 
        WHEN History.ID = 824 or Project.Name LIKE 'Example1%' or Project.Name LIKE 'Example2' or Project.Name like '%Example3%' 
          THEN 'Team One'
        WHEN History.ID = 814 OR Project.Name LIKE '%Example4%' 
          THEN 'Team Two' 
        ELSE 'Other' 
     END) as [Team],
     Project.Name as [Project],
     COUNT(Dial.ID) as [Total Avail.],
     COUNT (CASE 
               WHEN Dial.Flag = '1' AND Dial.Att = 0 OR Dial.Att > 0 AND Dial.Flag = 0 
               THEN 1 
               ELSE NULL 
            END) AS [Total Eligible],
     ISNULL(SUM(History.Attempt), 0) AS [Total Attempts],
     ROUND(COUNT(CAST(ISNULL(History.Attempt, 0) AS float)) / COUNT(CASE WHEN Dial.Flag = '1' OR Dial.Attempts > 0 THEN 1 ELSE NULL END), 2)*100 AS [Penetration %],
     COUNT(History.Attempt) as [Unique Attempts], 
     COUNT (CASE WHEN History.Code IN ('EX1','EX2','EX3','EX4','EX5') 
            THEN 1 ELSE NULL END) AS [Contacts],
     COUNT (CASE WHEN History.Code IN ('EX6','EX6','EX7') 
            THEN 1 ELSE NULL END)  AS [Success]
FROM 
     Dial Dial
LEFT JOIN 
     History History ON Dial.UID = History.UID
LEFT JOIN 
     Project Project ON Dial.ID = Project.ID
WHERE 
     Dial.Field2 NOT LIKE ''
     AND Dial.ID NOT LIKE '-%'
     AND History.DateTime > CONVERT(datetime, convert(char(8), getdate(), 112))
GROUP BY 
     Project.Name, History.ID

2 个答案:

答案 0 :(得分:0)

History.DateTime > CONVERT(datetime,convert(char(8),getdate(),112))中的行WHERE将“LEFT JOIN History变为内部联接,因此结果集不包含History表中没有相应条目的记录。将其移至连接条件:

LEFT JOIN History History ON (Dial.UID = History.UID 
 AND History.DateTime > CONVERT(datetime,convert(char(8),getdate(),112)))

答案 1 :(得分:0)

让我们看一下查询的fromwhere部分:

FROM Dial Dial LEFT JOIN
     History History
     ON Dial.UID = History.UID LEFT JOIN
     Project Project
     ON Dial.ID = Project.ID
WHERE Dial.Field2 NOT LIKE '' AND
      Dial.ID NOT LIKE '-%' AND
      History.DateTime > CONVERT(datetime,convert(char(8),getdate(),112))

您使用left join是正确的,因为您希望将所有内容保留在Dial表中。但是,您可以使用left join上的最后一次比较撤消History.DateTime。没有匹配记录时,它将为NULL。并且NULL将无法进行比较。您可以通过在coalesce()子句中添加is nullwhere来解决此问题。

另一个解决方法是将逻辑添加到on子句:

FROM Dial Dial LEFT JOIN
     History History
     ON Dial.UID = History.UID and
        History.DateTime > CONVERT(datetime,convert(char(8),getdate(),112)) LEFT JOIN
     Project Project
     ON Dial.ID = Project.ID
WHERE Dial.Field2 NOT LIKE '' AND
      Dial.ID NOT LIKE '-%'

如果您使用的是更新版本的SQL Server,则可以通过转换为date进行日期比较:

FROM Dial Dial LEFT JOIN
     History History
     ON Dial.UID = History.UID and
        History.DateTime > cast(getdate() as date) LEFT JOIN
     Project Project
     ON Dial.ID = Project.ID
WHERE Dial.Field2 NOT LIKE '' AND
      Dial.ID NOT LIKE '-%'

它使查询更容易阅读。