按where子句中的列表进行分组,然后显示该行是否具有值或为null

时间:2015-06-11 21:18:29

标签: sql sql-server join

我正在研究这个查询一段时间,我试图弄清楚如何让这个查询显示输出表中where clause的所有首字母,而不管该人是否有p。是不是。这是因为我将把这些信息放入预先格式化的Excel表格中。提前致谢!编辑:

SELECT 
    e.Initials, COUNT(p.Id) As "NT > 7"
FROM 
    Employees AS e
LEFT JOIN 
    Projects AS p
ON 
    e.Id = p.NTEmployeeId AND
    cast(p.NTDate as Datetime) < cast(dateadd(day, -7, (getdate())) as Datetime)
JOIN 
    Statuses AS s
ON 
    s.Id = p.StatusId AND
    s.Code in ('WIPR', 'RISK', 'PEND')
WHERE 
    e.Initials IN('af', 'cm' , 'jy','br','dfv','rxc','tm','axk','hd','sa','rw')
 GROUP BY (e.Initials);

2 个答案:

答案 0 :(得分:1)

您需要额外的left join并将除第一个表之外的所有条件移至on子句中。请记住,where子句会将外连接转换为内连接,因为NULL值不会(通常)匹配条件。

SELECT e.Initials, COUNT(p.Id) As "NT > 7"
FROM Employees e LEFT JOIN 
     Projects p
     ON e.Id = p.NTEmployeeId AND
        cast(p.NTDate as Date) < cast(getdate() as date)  -- do date comparisons as dates, not strings
     LEFT JOIN  -- NEED LEFT JOIN HERE, or `ON` clause turns it into inner join
     Statuses s
     ON s.Id = p.StatusId AND
        s.Code in ('WIPR', 'RISK', 'PEND') -- `LIKE`/`OR` isn't wrong but `IN` is easier
WHERE e.Initials IN ('af', 'cm' , 'jy', 'br','dfv', 'rxc', 'tm', 'axk', 'hd', 'sa', 'rw')
 GROUP BY e.Initials;

我做了其他一些改动:

  • 使用日期来比较日期,而不是字符串。我认为我有正确的逻辑。
  • 如果可以,请使用IN代替OR的链。
  • 对于你正在做的事情,你可能想要计算匹配的状态而不是匹配的人。

答案 1 :(得分:0)

我想出了我需要做些什么才能得到正确的答案来展示。请参阅以下内容:

SELECT
    e.Initials, COUNT(CASE WHEN s.Code in ('WIPR', 'RISK', 'PEND') 
and cast(p.NTDate as Datetime) < cast(dateadd(day, -7, (getdate())) as Datetime) THEN p.Id END) As "NT > 7"
FROM 
    Employees AS e
LEFT JOIN 
    Projects AS p
ON 
    e.Id = p.NTEmployeeId
JOIN 
    Statuses AS s
ON 
    s.Id = p.StatusId
WHERE 
     e.Initials IN('af', 'cm' , 'jy','br','dfv','rxc','tm','axk','hxd','rw')
GROUP BY (e.Initials);