Oracle SQL - 添加 CASE 语句后“不是按表达式分组”

Posted

技术标签:

【中文标题】Oracle SQL - 添加 CASE 语句后“不是按表达式分组”【英文标题】:Oracle SQL - "Not a group by expression" after adding CASE statements 【发布时间】:2018-11-02 15:41:38 【问题描述】:

我有很长的查询,我必须添加两个新的 CASE 语句 -

SELECT nt.COSTCENTER,
s.DAD,
s.DIVISION, 
nt.DISPENSER,
UPPER(nt.TINTERSERIALNBR),
COUNT(*)OVER (PARTITION BY nt.COSTCENTER) AS NumOfDispensers,
nt.CLRNTSYS,
SUM(CASE WHEN
(nt.CLRNTSYS ='CCE' AND (nt.BOOKDATE >= '01-JAN-17' AND nt.BOOKDATE <= '31-DEC-17')) 
THEN nt.GALLONS ELSE 0 END) AS CCEGallons2017,
SUM(CASE WHEN
(nt.CLRNTSYS ='BAC' AND (nt.BOOKDATE >= '01-JAN-17' AND nt.BOOKDATE <= '31-DEC-17'))
THEN nt.GALLONS ELSE 0 END) AS BACGallons2017,
SUM(CASE WHEN
(nt.CLRNTSYS ='CCE' AND (nt.BOOKDATE >= '01-JAN-18' AND nt.BOOKDATE <= '31-DEC-18')) 
THEN nt.GALLONS ELSE 0 END) AS CCEGallons2018,
SUM(CASE WHEN
(nt.CLRNTSYS ='BAC' AND (nt.BOOKDATE >= '01-JAN-18' AND nt.BOOKDATE <= '31-DEC-18'))
THEN nt.GALLONS ELSE 0 END) AS BACGallons2018,
CASE WHEN to_char(tm.DNRDATE,'YYYY') = '2017' THEN 'YES' ELSE 'NO' END DNR2017,
CASE WHEN to_char(tm.DNRDATE,'YYYY') = '2018' THEN 'YES' ELSE 'NO' END DNR2018
FROM MQ_CDS_NETTRAN nt
INNER JOIN MQCCNSTORE s
ON nt.COSTCENTER = s.COSTCENTER
INNER JOIN TINTER_MASTER tm
ON UPPER(nt.TINTERSERIALNBR) = UPPER(tm.SERIALNBR)
WHERE nt.BOOKDATE >= '01-JAN-17'
AND nt.CLRNTSYS IN ('CCE','BAC')
AND nt.TRANCODE = 'DISP'
AND UPPER(nt.DISPENSER) <> 'BYHAND'
AND UPPER(nt.DISPENSER) <> 'STANDALONE'
AND tm.DECOMMDATE IS NULL
GROUP BY nt.COSTCENTER, nt.DISPENSER, UPPER(nt.TINTERSERIALNBR), nt.CLRNTSYS,
s.DAD, s.DIVISION
ORDER BY nt.COSTCENTER, nt.DISPENSER, UPPER(nt.TINTERSERIALNBR), nt.CLRNTSYS;

这是我添加到查询中的两条 CASE 行:

CASE WHEN to_char(tm.DNRDATE,'YYYY') = '2017' THEN 'YES' ELSE 'NO' END DNR2017,
CASE WHEN to_char(tm.DNRDATE,'YYYY') = '2018' THEN 'YES' ELSE 'NO' END DNR2018

当我尝试运行查询时,我得到“Not a group by expression”。在添加这两行之前,查询运行得很好。如何最好地纠正这个问题?

【问题讨论】:

除了答案,请不要依赖字符串和日期之间的隐式转换。相反,(假设您的 nt.bookdate 列是 DATE 数据类型),您应该使用 to_date() 或 ANSI DATE 文字,例如to_date('01/01/2018', 'dd/mm/yyyy')DATE '2018-01-01'. With your current query, if the NLS_DATE_FORMAT parameter was changed (e.g. after running alter session set nls_date_format = dd/mm/yyyy hh24:mi:ss`),您的查询可能会出错。始终是明确的,这样你的代码应该运行而不管 nls 设置。 【参考方案1】:

你需要让CASE WHEN加入group by,因为CASE WHEN不是聚合函数。

SELECT nt.COSTCENTER,
    s.DAD,
    s.DIVISION, 
    nt.DISPENSER,
    UPPER(nt.TINTERSERIALNBR),
    COUNT(*)OVER (PARTITION BY nt.COSTCENTER) AS NumOfDispensers,
    nt.CLRNTSYS,
    SUM(CASE WHEN
    (nt.CLRNTSYS ='CCE' AND (nt.BOOKDATE >= '01-JAN-17' AND nt.BOOKDATE <= '31-DEC-17')) 
    THEN nt.GALLONS ELSE 0 END) AS CCEGallons2017,
    SUM(CASE WHEN
    (nt.CLRNTSYS ='BAC' AND (nt.BOOKDATE >= '01-JAN-17' AND nt.BOOKDATE <= '31-DEC-17'))
    THEN nt.GALLONS ELSE 0 END) AS BACGallons2017,
    SUM(CASE WHEN
    (nt.CLRNTSYS ='CCE' AND (nt.BOOKDATE >= '01-JAN-18' AND nt.BOOKDATE <= '31-DEC-18')) 
    THEN nt.GALLONS ELSE 0 END) AS CCEGallons2018,
    SUM(CASE WHEN
    (nt.CLRNTSYS ='BAC' AND (nt.BOOKDATE >= '01-JAN-18' AND nt.BOOKDATE <= '31-DEC-18'))
    THEN nt.GALLONS ELSE 0 END) AS BACGallons2018,
    CASE WHEN to_char(tm.DNRDATE,'YYYY') = '2017' THEN 'YES' ELSE 'NO' END DNR2017,
    CASE WHEN to_char(tm.DNRDATE,'YYYY') = '2018' THEN 'YES' ELSE 'NO' END DNR2018
FROM MQ_CDS_NETTRAN nt
INNER JOIN MQCCNSTORE s ON nt.COSTCENTER = s.COSTCENTER
INNER JOIN TINTER_MASTER tm ON UPPER(nt.TINTERSERIALNBR) = UPPER(tm.SERIALNBR)
WHERE 
        nt.BOOKDATE >= '01-JAN-17'
    AND nt.CLRNTSYS IN ('CCE','BAC')
    AND nt.TRANCODE = 'DISP'
    AND UPPER(nt.DISPENSER) <> 'BYHAND'
    AND UPPER(nt.DISPENSER) <> 'STANDALONE'
    AND tm.DECOMMDATE IS NULL
GROUP BY 
    nt.COSTCENTER, 
    nt.DISPENSER, 
    UPPER(nt.TINTERSERIALNBR),
    nt.CLRNTSYS,
    s.DAD, 
    s.DIVISION,
    CASE WHEN to_char(tm.DNRDATE,'YYYY') = '2017' THEN 'YES' ELSE 'NO' END,
    CASE WHEN to_char(tm.DNRDATE,'YYYY') = '2018' THEN 'YES' ELSE 'NO' END
ORDER BY nt.COSTCENTER, nt.DISPENSER, UPPER(nt.TINTERSERIALNBR), nt.CLRNTSYS;

【讨论】:

这似乎有效 - 我被它说“不是按表达式分组”而不是实际上是需要添加到 GROUP BY 部分的按表达式分组。

以上是关于Oracle SQL - 添加 CASE 语句后“不是按表达式分组”的主要内容,如果未能解决你的问题,请参考以下文章

SQL语句case怎么判断这个字段为空

CASE 语句 [Oracle/SQL]

oracle sql case语句

CASE SQL 语句 oracle 数据库

ORACLE SQL CASE 语句 - 出现错误

LIKE 在 CASE 语句中 Oracle SQL (Sql Developer)