【问题标题】:Getting null value from Attendance Log table and Employee table using SQL Server query?使用 SQL Server 查询从考勤日志表和员工表中获取空值?
【发布时间】:2015-07-27 14:59:04
【问题描述】:

我有这样的查询来提取数据:

SELECT 
    e.EmpName,
    d.DepartmentName,
    l.EnrollNumber,
    v.VerifyModeName,
    CAST(PunchTime as DATE)Check_Date,MIN(CAST(PunchTime as Time))[TimeIN], MAX(Cast(PunchTime as Time))[TimeOUT],
        RIGHT('0' + CAST(DATEDIFF(SECOND, MIN(CAST(PunchTime as Time)), MAX(Cast(PunchTime as Time))) / 3600 AS VARCHAR),2) + ':' +
        RIGHT('0' + CAST((DATEDIFF(SECOND, MIN(CAST(PunchTime as Time)), MAX(Cast(PunchTime as Time))) / 60) % 60 AS VARCHAR),2)  + ':' +
        RIGHT('0' + CAST(DATEDIFF(SECOND, MIN(CAST(PunchTime as Time)), MAX(Cast(PunchTime as Time))) % 60 AS VARCHAR),2) as Duration
FROM 
    Department d, 
    VerifyModes v, 
    Employee e 
FULL OUTER JOIN AttLog l 
    ON e.EnrollNumber=l.EnrollNumber
WHERE
    e.DeptID = d.Id
    AND l.VerifyMode = v.VerifyModeId 
GROUP BY 
    e.EmpName, d.DepartmentName, l.EnrollNumber, v.VerifyModeName, CAST(PunchTime as DATE)
ORDER BY Check_Date

结果是这样的:

虽然我已经包含了full outer join 条件。

如果我只使用:

select e.EmpName, l.PunchTime 
from Employee e 
full outer join AttLog l 
    on e.EnrollNumber = l.EnrollNumber

结果显示EmployeeNULL PunchTime

那么,如何修复上述查询以获得包含NULL PunchTime 的结果?

然后,当我添加日期条件时,查询仍然没有再次显示 NULL 。如何纠正?

SELECT 
            e.EmpName,
            d.DepartmentName,
            l.EnrollNumber,
            v.VerifyModeName,
            CAST(PunchTime as DATE)Check_Date,MIN(CAST(PunchTime as Time))[TimeIN], MAX(Cast(PunchTime as Time))[TimeOUT],
                RIGHT('0' + CAST(DATEDIFF(SECOND, MIN(CAST(PunchTime as Time)), MAX(Cast(PunchTime as Time))) / 3600 AS VARCHAR),2) + ':' +
                RIGHT('0' + CAST((DATEDIFF(SECOND, MIN(CAST(PunchTime as Time)), MAX(Cast(PunchTime as Time))) / 60) % 60 AS VARCHAR),2)  + ':' +
                RIGHT('0' + CAST(DATEDIFF(SECOND, MIN(CAST(PunchTime as Time)), MAX(Cast(PunchTime as Time))) % 60 AS VARCHAR),2) as Duration
        FROM Department d    
        INNER JOIN Employee e
            ON e.DeptID = d.Id
        LEFT JOIN AttLog l 
            ON e.EnrollNumber = l.EnrollNumber
        LEFT JOIN VerifyModes v
            ON l.VerifyMode = v.VerifyModeId 
        WHERE cast(l.PunchTime as Date) between '2015-07-22' and '2015-07-22'
        GROUP BY 
            e.EmpName, d.DepartmentName, l.EnrollNumber, v.VerifyModeName, CAST(PunchTime as DATE)

        ORDER BY Check_Date

【问题讨论】:

  • 把日期比较放在ON子句中。

标签: sql-server


【解决方案1】:

尝试改用LEFT JOIN

SELECT 
    e.EmpName,
    d.DepartmentName,
    l.EnrollNumber,
    v.VerifyModeName,
    CAST(PunchTime as DATE)Check_Date,MIN(CAST(PunchTime as Time))[TimeIN], MAX(Cast(PunchTime as Time))[TimeOUT],
        RIGHT('0' + CAST(DATEDIFF(SECOND, MIN(CAST(PunchTime as Time)), MAX(Cast(PunchTime as Time))) / 3600 AS VARCHAR),2) + ':' +
        RIGHT('0' + CAST((DATEDIFF(SECOND, MIN(CAST(PunchTime as Time)), MAX(Cast(PunchTime as Time))) / 60) % 60 AS VARCHAR),2)  + ':' +
        RIGHT('0' + CAST(DATEDIFF(SECOND, MIN(CAST(PunchTime as Time)), MAX(Cast(PunchTime as Time))) % 60 AS VARCHAR),2) as Duration
FROM Department d    
INNER JOIN Employee e
    ON e.DeptID = d.Id
LEFT JOIN AttLog l 
    ON e.EnrollNumber = l.EnrollNumber
LEFT JOIN VerifyModes
    ON l.VerifyMode = v.VerifyModeId 
GROUP BY 
    e.EmpName, d.DepartmentName, l.EnrollNumber, v.VerifyModeName, CAST(PunchTime as DATE)
ORDER BY Check_Date

注意:Avoid using old-style JOIN syntax.


编辑: 不要将日期比较放在WHERE 子句中,而是将其放在JOIN 条件中:

LEFT JOIN Attlog l
    ON e.DeptID = d.Id
    AND cast(l.PunchTime as Date) between '2015-07-22' and '2015-07-22'

将比较放在WHERE 子句中会将查询转换为INNER JOIN,从而删除NULL 行。

【讨论】:

  • 请帮忙,如果我为查询添加日期条件,它仍然不显示谁有 NULL PunchTime
  • 将日期放在JOIN 条件而不是WHERE 子句中。
  • 我将 WHERE 替换为“在 '2015-07-22' 和 '2015-07-22' 之间加入演员(l.PunchTime as Date)”,但得到错误:关键字'附近的语法不正确作为'。
  • 没问题,很高兴我能帮上忙。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-21
  • 1970-01-01
  • 2016-07-20
  • 1970-01-01
  • 2017-02-10
  • 1970-01-01
相关资源
最近更新 更多