CASE陈述式中WHEN的GROUP BY问题

时间:2020-01-21 16:04:28

标签: sql group-by count pivot

我试图将间接和直接小时数全部显示在一行上,并且我知道由于group by语句而出现了多行。但是,我尝试删除分组,并得到一个错误:删除时l.CHG_TYPE不包含在聚合中。

<html><table><body><tr><th>ID</th><th>Billing Period</th><th>Shop</th><th>Shift Code</th><th>Employee #</th><th>Indirect Hours</th><th>Direct Hours</th></tr><tr class="odd"><td>202001404223396</td><td>202001</td><td>Sanitation</td><td>1st</td><td>23396</td><td>&nbsp;</td><td>12.73</td></tr>
<tr><td>202001404223396</td><td>202001</td><td>Sanitation</td><td>1st</td><td>23396</td><td>6.41</td><td>&nbsp;</td></tr>
<tr class="odd"><td>202001205225499</td><td>202001</td><td>Car Shop</td><td>1st</td><td>25499</td><td>&nbsp;</td><td>12.4</td></tr>
<tr><td>202001205225499</td><td>202001</td><td>Car Shop</td><td>1st</td><td>25499</td><td>6.82</td><td>&nbsp;</td></tr>
</table></body></html>

SELECT
    CONCAT(l.FISC_PD, l.LOCATION, l.SHIFT_CODE, e.EmpNo) 'ID',
    l.FISC_PD 'Billing Period', 
    CASE
        WHEN l.LOCATION = '202' THEN 'Specialty Equipment' 
        WHEN l.LOCATION = '205' THEN 'Car Shop'
        WHEN l.LOCATION = '206' THEN 'Truck Shop'
        WHEN l.LOCATION = '404' THEN 'Sanitation'
        WHEN l.LOCATION = '212' THEN 'Tire Shop'
        ELSE l.LOCATION
    END as 'Shop',
    CASE
        WHEN l.SHIFT_CODE in ('2','6') THEN '1st'
        WHEN l.SHIFT_CODE in ('3','4','5') THEN '2nd'
        ELSE NULL
    END as 'Shift Code',
    e.EmpNo 'Employee #',
    CASE
        WHEN l.CHG_TYPE = 'I' THEN ROUND((SUM(l.DURATION)/36000000),2)
        ELSE NULL
    END as 'Indirect Hours',
    CASE
        WHEN l.CHG_TYPE = 'D' THEN ROUND((SUM(l.DURATION)/36000000),2)
        ELSE NULL
    END as 'Direct Hours'
FROM m5prod.mfive.VIEW_EMP_LABOR_JNL l
LEFT JOIN m5prod.mfive.VIEW_ALL_EMPLOYEES e on e.EmpID = l.EMP_ID
WHERE 
    l.location not in ('218', '201')
    and l.FISC_PD in ('202001', '202002', '202003')
GROUP BY
    l.FISC_PD,  
    e.EmpNo,
    l.LOCATION,
    l.SHIFT_CODE,
    l.CHG_TYPE

1 个答案:

答案 0 :(得分:2)

您可以按以下方式使用条件聚合:

  • CHG_TYPE子句中删除GROUP BY
  • CASE内移动SUM()表达式
SELECT
    CONCAT(l.FISC_PD, l.LOCATION, l.SHIFT_CODE, e.EmpNo) 'ID',
    l.FISC_PD 'Billing Period', 
    CASE
        WHEN l.LOCATION = '202' THEN 'Specialty Equipment' 
        WHEN l.LOCATION = '205' THEN 'Car Shop'
        WHEN l.LOCATION = '206' THEN 'Truck Shop'
        WHEN l.LOCATION = '404' THEN 'Sanitation'
        WHEN l.LOCATION = '212' THEN 'Tire Shop'
        ELSE l.LOCATION
    END as 'Shop',
    CASE
        WHEN l.SHIFT_CODE in ('2','6') THEN '1st'
        WHEN l.SHIFT_CODE in ('3','4','5') THEN '2nd'
        ELSE NULL
    END as 'Shift Code',
    e.EmpNo 'Employee #',
    ROUND(SUM(CASE WHEN l.CHG_TYPE = 'I' THEN l.DURATION END)/36000000),2) as 'Indirect Hours',
    ROUND(SUM(CASE WHEN l.CHG_TYPE = 'D' THEN l.DURATION END)/36000000),2) as 'Direct Hours'
FROM m5prod.mfive.VIEW_EMP_LABOR_JNL l
LEFT JOIN m5prod.mfive.VIEW_ALL_EMPLOYEES e on e.EmpID = l.EMP_ID
WHERE 
    l.location not in ('218', '201')
    and l.FISC_PD in ('202001', '202002', '202003')
GROUP BY
    l.FISC_PD,  
    e.EmpNo,
    l.LOCATION,
    l.SHIFT_CODE

侧面说明:对列别名使用单引号不是一个好习惯。在标准SQL中,单引号保留给字符串文字。我建议对数据库使用相关的引号字符(MySQL:反引号-SQL Server:方括号-Postgres和Oracle:双引号)。更好的是,您可以使用不包含特殊字符的列别名,因此不需要用引号引起来。