总小时列返回两个输出而不是一个

时间:2014-07-14 13:09:26

标签: sql sql-server sql-server-2008

以下查询工作正常,但它返回两行小时,我不想

SELECT
    USERINFO.name, USERINFO.BADGENUMBER, 
    departments.deptname, APPROVEDHRS.hours,
    sum(workingdays) as workingdays,TotalWorkingDays
FROM
    (SELECT DISTINCT 
         (DATEDIFF(DAY, '2014-06-01', '2014-06-30') + 1) -
          DATEDIFF(WEEK, '2014-06-01', '2014-06-30') * 2 - 
          (CASE WHEN DATEPART(WEEKDAY, '2014-06-01') = 5 THEN 1 ELSE 0 END) - 
          (CASE WHEN DATEPART(WEEKDAY, '2014-06-30') = 6 THEN 1 ELSE 0 END) AS TotalWorkingDays, 
         COUNT(DISTINCT DATEADD(d, 0,DATEDIFF(d, 0, CHECKINOUT.CHECKTIME))) AS workingdays,
         USERINFO.BADGENUMBER, USERINFO.NAME, hours
     FROM  
         USERINFO 
     LEFT JOIN 
         CHECKINOUT ON USERINFO.USERID = CHECKINOUT.USERID 
     LEFT JOIN 
         departments ON departments.deptid = userinfo.DEFAULTDEPTID
     LEFT JOIN 
         APPROVEDHRS ON APPROVEDHRS.userid = userinfo.userid
     WHERE
         (DEPARTMENTS.DEPTNAME = 'xyz') 
         AND (CHECKINOUT.CHECKTIME >= '2014-06-01') 
         AND (CHECKINOUT.CHECKTIME <= '2014-06-30') 
     GROUP BY 
         hours, USERINFO.BADGENUMBER, deptname, USERINFO.NAME,
         CONVERT(VARCHAR(10), CHECKINOUT.CHECKTIME, 103)) blue
GROUP BY 
    name, BADGENUMBER, workingdays, TotalWorkingDays, deptname, hours

以上查询的输出:

name    BADGENUMBER     deptname        hours   
---------------------------------------------------
abc     1111             xyz            00:07:59    
abc     1111             xyz            00:08:00    
pqr     2222             qwe            NULL

现在表中的总小时数(APPROVEDHRS表)是:

BADGENUMBER     NAME    DATE        HOURS
-------------------------------------------------
1111            xyz  2014-06-15     00:07:59
1111            xyz  2014-06-14     00:08:00
1111            xyz  2014-07-20     00:10:00

我正在从2014-06-01到2014-06-30获取记录

所以我想要以下输出:

name       BADGENUMBER      deptname        hours   
--------------------------------------------------------       
    abc     1111             xyz            00:15:59    

    pqr     2222            qwe             NULL

帮助我获得所需的输出。

谢谢

3 个答案:

答案 0 :(得分:0)

如果您正在加入ApprovedHrs表,那么您需要限制(使用Where子句或join子句)7月份批准的小时数来自的日期。

为了澄清这一点,我将使用ApprovedHrs.Hours完全限定小时字段,以便更清楚它来自何处(我只假设“小时”来自ApprovedHrs - 如果我错了,请纠正我)

你刚刚加入了userid,所以看起来ApprovedHrs会为ApprovedHrs的用户带来一切.-- Jim

答案 1 :(得分:0)

首先,您可能希望在查询中使用表名,以便查看数据的来源,例如:

select name,BADGENUMBER,deptname,hours,

...会更容易理解为:

select ??.name,??.BADGENUMBER,??.deptname,APPROVEDHRS.hours,

...或者您可以在查询的“FROM”部分使用别名,以便更容易理解?

无论如何,基本问题似乎是您按日期过滤了CHECKINOUT表,但您没有过滤APPROVEDHRS表。要解决这个问题,你可以改变你的JOIN:

left join APPROVEDHRS on APPROVEDHRS.userid = userinfo.userid

到此:

left join APPROVEDHRS on APPROVEDHRS.userid = userinfo.userid
AND (APPROVEDHRS.DATE >='2014-06-01') AND (APPROVEDHRS.DATE <='2014-06-30')

...并回答您的问题(可能应该在StackOverflow上创建一个新问题)。这取决于[hours]字段的数据类型。我试图将你的查询作为一个起点,但如果不知道数据类型是什么等,这有点棘手。

所以看起来小时是一个VARCHAR(?),看起来很奇怪,但是请注意,我假设你的“小时”字段总是采用“??:HH:MM.SSS”格式您只想添加小时和分钟:

WITH Data AS (
    SELECT 
        DATEDIFF(DAY, '2014-06-01', '2014-06-30') + 1 -
            DATEDIFF(WEEK, '2014-06-01', '2014-06-30') * 2 - 
            CASE WHEN DATEPART(WEEKDAY, '2014-06-01') = 5 THEN 1 ELSE 0 END - 
            CASE WHEN DATEPART(WEEKDAY, '2014-06-30') = 6 THEN 1 ELSE 0 END AS TotalWorkingDays, 
        COUNT(DISTINCT DATEADD(d, 0,DATEDIFF(d, 0, c.CHECKTIME))) AS WorkingDays,
        d.deptname,
        u.BADGENUMBER, 
        u.NAME, 
        CONVERT(INT, SUBSTRING([Hours], 4, 2)) AS [hours],
            CONVERT(INT, SUBSTRING([Hours], 7, 2)) AS [minutes]
    FROM  
        USERINFO u
        LEFT JOIN CHECKINOUT c ON c.USERID = u.USERID 
        LEFT JOIN departments d ON d.deptid = u.DEFAULTDEPTID
        LEFT JOIN APPROVEDHRS a ON a.userid = u.USERID
    WHERE
        d.DEPTNAME = 'xyz'
        AND c.CHECKTIME >= '2014-06-01'
        AND c.CHECKTIME <= '2014-06-30'
    GROUP BY
        d.deptname,
        u.BADGENUMBER, 
        u.NAME, 
        CONVERT(INT, SUBSTRING([Hours], 4, 2)),
            CONVERT(INT, SUBSTRING([Hours], 7, 2)))
SELECT
    Name, 
    BADGENUMBER, 
    deptname, 
    '00:' + CONVERT(VARCHAR(3), SUM([hours]) + ':' + CONVERT(VARCHAR(3), SUM([minutes]) + '.000' AS [Hours],
    SUM(WorkingDays) AS WorkingDays,
    TotalWorkingDays
FROM
    Data
GROUP BY 
    Name, 
    BADGENUMBER, 
    deptname,
    TotalWorkingDays;

......如果有效,我会感到惊讶:P

答案 2 :(得分:0)

我认为这是因为GROUP BY hourshours值不同时会为该记录创建一个新行