聚合 in case 语句并出现 "not a GROUP BY expression" 错误
Aggregate in case statement with "not a GROUP BY expression" error
为什么在我的查询中包含以下 case 语句时出现“不是 GROUP BY 表达式”错误,即使下面的 case 语句使用了 GROUP BY 中不允许的聚合?
当我在 GROUP BY 中包含 case 语句时,当然会出现“此处不允许使用组函数”错误,但是当我将其从 GROUP BY 中删除时,我会再次出现“不是 GROUP BY 表达式”错误。
谁能解释一下,好吗?提前致谢!
,case
when
round(sum(i.INVOICE_AMOUNT)) > 50000 and
(cont_all.CONTRACT_EFFECTIVE_DATE > '&end_date'
or cont_all.CONTRACT_EXPIRATION_DATE <= '&end_date'
or cont_all.CONTRACT_EFFECTIVE_DATE is null)
then 'Over 50k and no Contract'
else 'Contract or No Contract with spend below 50k'
end as "Contract Needed?"
这是 mathguy 建议的完整查询:
define end_date = '30-SEP-20'
select
v.SEGMENT1 "Vendor Number"
,v.VENDOR_NAME "Vendor Name"
,s.VENDOR_SITE_CODE "Site Name"
,case
when s.ORG_ID in ('285', '296', '294', '327', '304', '297', '295', '312', '313', '315', '319', '322', '321', '306') then 'Fleet'
else 'Non-Fleet'
end as "Fleet / Non-Fleet"
,case
when s.ORG_ID in ('288','325','285') then 'Belgium'
when s.ORG_ID in ('301','296','302','294') then 'Germany'
when s.ORG_ID in ('327','305','304') then 'Spain'
when s.ORG_ID in ('298','303','297','299','300','295') then 'France'
when s.ORG_ID in ('309','307') then 'Ireland'
when s.ORG_ID in ('316','312','314','317','313') then 'Italy'
when s.ORG_ID in ('318','315') then 'Luxembourg'
when s.ORG_ID in ('318','315') then 'Monaco'
when s.ORG_ID in ('322','323','324','326','321') then 'Netherlands'
when s.ORG_ID in ('308','310','311','306') then 'United Kingdom'
else 'Error'
end as "Country"
,o.NAME "Operating Unit"
,to_number(round(sum(i.INVOICE_AMOUNT))) "Spend last 12 months"
,case
when round(sum(i.INVOICE_AMOUNT)) > 50000 then 'Over 50,000'
when round(sum(i.INVOICE_AMOUNT)) <= 50000 then 'Below 50,000'
when round(sum(i.INVOICE_AMOUNT)) = 0 then 'No spend'
when round(sum(i.INVOICE_AMOUNT)) is null then 'No spend'
else 'Wrong'
end as "Spend brackets last 12 months"
,case
when cont_all.CONTRACT_EFFECTIVE_DATE <='&end_date' then 'Contract'
when cont_all.CONTRACT_EFFECTIVE_DATE > '&end_date' then 'No Contract'
when cont_all.CONTRACT_EXPIRATION_DATE <= '&end_date' then 'No Contract'
when cont_all.CONTRACT_EXPIRATION_DATE > '&end_date' then 'Contract'
when cont_all.CONTRACT_EFFECTIVE_DATE is null then 'No Contract'
else 'Wrong'
end as "Contract Indicator"
-- ,case
-- when
-- round(sum(i.INVOICE_AMOUNT)) > 50000 and
-- (cont_all.CONTRACT_EFFECTIVE_DATE > '&end_date'
-- or cont_all.CONTRACT_EXPIRATION_DATE <= '&end_date'
-- or cont_all.CONTRACT_EFFECTIVE_DATE is null)
-- then 'Over 50k and no Contract'
-- else 'Contract or No Contract with spend below 50k'
-- end as "Contract Needed?"
,t.NAME "Terms"
,TO_CHAR(TO_DATE('&end_date', 'DD-MON-YYYY'), 'Mon YY') Month
from
AP.AP_SUPPLIERS v
join AP.AP_SUPPLIER_SITES_ALL s on v.VENDOR_ID=s.VENDOR_ID
join apps.HR_ALL_ORGANIZATION_UNITS o on s.ORG_ID=o.ORGANIZATION_ID
left join AP.AP_INVOICES_ALL i on s.VENDOR_SITE_ID=i.VENDOR_SITE_ID
left join AP_TERMS_TL t on s.TERMS_ID=t.TERM_ID
left join APPS.OKC_REP_CONTRACT_PARTIES cont on v.VENDOR_ID=cont.PARTY_ID
left join APPS.OKC_REP_CONTRACTS_ALL cont_all on cont.CONTRACT_ID=cont_all.CONTRACT_ID
where
((v.end_date_active is null or v.end_date_active > '&end_date') and (s.inactive_date is null or s.inactive_date > '&end_date'))
and v.CREATION_DATE <= '&end_date'
and s.ORG_ID in ('324','288','325','285','301','296','302','294','327','305','304','298','303','297','299','300','295','309','307','316','312','314','317','313','318','315','320','319','322','323','326','321','308','310','311','306')
and v.SEGMENT1 = 259456
and i.CREATION_DATE between add_months('&end_date', -12) and '&end_date'
and i.CANCELLED_DATE is null
group by
v.SEGMENT1
,v.VENDOR_NAME
,s.VENDOR_SITE_CODE
,case
when s.ORG_ID in ('285', '296', '294', '327', '304', '297', '295', '312', '313', '315', '319', '322', '321', '306') then 'Fleet'
else 'Non-Fleet'
end
,case
when s.ORG_ID in ('288','325','285') then 'Belgium'
when s.ORG_ID in ('301','296','302','294') then 'Germany'
when s.ORG_ID in ('327','305','304') then 'Spain'
when s.ORG_ID in ('298','303','297','299','300','295') then 'France'
when s.ORG_ID in ('309','307') then 'Ireland'
when s.ORG_ID in ('316','312','314','317','313') then 'Italy'
when s.ORG_ID in ('318','315') then 'Luxembourg'
when s.ORG_ID in ('318','315') then 'Monaco'
when s.ORG_ID in ('322','323','324','326','321') then 'Netherlands'
when s.ORG_ID in ('308','310','311','306') then 'United Kingdom'
else 'Error'
end
,o.NAME
,case
when cont_all.CONTRACT_EFFECTIVE_DATE <='&end_date' then 'Contract'
when cont_all.CONTRACT_EFFECTIVE_DATE > '&end_date' then 'No Contract'
when cont_all.CONTRACT_EXPIRATION_DATE <= '&end_date' then 'No Contract'
when cont_all.CONTRACT_EXPIRATION_DATE > '&end_date' then 'Contract'
when cont_all.CONTRACT_EFFECTIVE_DATE is null then 'No Contract'
else 'Wrong'
end
-- ,case
-- when
-- (round(sum(i.INVOICE_AMOUNT)) > 50000
-- and
-- (cont_all.CONTRACT_EFFECTIVE_DATE > '&end_date'
-- or cont_all.CONTRACT_EXPIRATION_DATE <= '&end_date'
-- or cont_all.CONTRACT_EFFECTIVE_DATE is null) )
-- then 'Over 50k and no Contract'
-- else 'Contract or No Contract with spend below 50k'
-- end
,t.NAME
,TO_CHAR(TO_DATE('&end_date', 'DD-MON-YYYY'), 'Mon YY')
这是您的简化示例
create table tab as
select
1 SEGMENT1,
sysdate + rownum as CONTRACT_EFFECTIVE_DATE, rownum INVOICE_AMOUNT from dual
connect by level <= 10;
select
SEGMENT1,
case when sum(INVOICE_AMOUNT) > 50 and CONTRACT_EFFECTIVE_DATE > DATE'2020-01-01' then 'OK' else 'NOK' end as col1
from tab
group by SEGMENT1;
这当然会导致 ORA-00979: not a GROUP BY expression
因为你 不 group by
CONTRACT_EFFECTIVE_DATE
但是添加 CONTRACT_EFFECTIVE_DATE
很可能不是您想要的。
我想你需要把过滤条件 放入 聚合函数中,像这样 - 所以你只聚合 INVOICE_AMOUNT
如果条件是完整的并进行比较结果与阈值
select
SEGMENT1,
case when
sum(case when CONTRACT_EFFECTIVE_DATE > DATE'2020-01-01'then INVOICE_AMOUNT end) > 50
then 'OK' else 'NOK' end as col1
from tab
group by SEGMENT1;
为什么在我的查询中包含以下 case 语句时出现“不是 GROUP BY 表达式”错误,即使下面的 case 语句使用了 GROUP BY 中不允许的聚合? 当我在 GROUP BY 中包含 case 语句时,当然会出现“此处不允许使用组函数”错误,但是当我将其从 GROUP BY 中删除时,我会再次出现“不是 GROUP BY 表达式”错误。
谁能解释一下,好吗?提前致谢!
,case
when
round(sum(i.INVOICE_AMOUNT)) > 50000 and
(cont_all.CONTRACT_EFFECTIVE_DATE > '&end_date'
or cont_all.CONTRACT_EXPIRATION_DATE <= '&end_date'
or cont_all.CONTRACT_EFFECTIVE_DATE is null)
then 'Over 50k and no Contract'
else 'Contract or No Contract with spend below 50k'
end as "Contract Needed?"
这是 mathguy 建议的完整查询:
define end_date = '30-SEP-20'
select
v.SEGMENT1 "Vendor Number"
,v.VENDOR_NAME "Vendor Name"
,s.VENDOR_SITE_CODE "Site Name"
,case
when s.ORG_ID in ('285', '296', '294', '327', '304', '297', '295', '312', '313', '315', '319', '322', '321', '306') then 'Fleet'
else 'Non-Fleet'
end as "Fleet / Non-Fleet"
,case
when s.ORG_ID in ('288','325','285') then 'Belgium'
when s.ORG_ID in ('301','296','302','294') then 'Germany'
when s.ORG_ID in ('327','305','304') then 'Spain'
when s.ORG_ID in ('298','303','297','299','300','295') then 'France'
when s.ORG_ID in ('309','307') then 'Ireland'
when s.ORG_ID in ('316','312','314','317','313') then 'Italy'
when s.ORG_ID in ('318','315') then 'Luxembourg'
when s.ORG_ID in ('318','315') then 'Monaco'
when s.ORG_ID in ('322','323','324','326','321') then 'Netherlands'
when s.ORG_ID in ('308','310','311','306') then 'United Kingdom'
else 'Error'
end as "Country"
,o.NAME "Operating Unit"
,to_number(round(sum(i.INVOICE_AMOUNT))) "Spend last 12 months"
,case
when round(sum(i.INVOICE_AMOUNT)) > 50000 then 'Over 50,000'
when round(sum(i.INVOICE_AMOUNT)) <= 50000 then 'Below 50,000'
when round(sum(i.INVOICE_AMOUNT)) = 0 then 'No spend'
when round(sum(i.INVOICE_AMOUNT)) is null then 'No spend'
else 'Wrong'
end as "Spend brackets last 12 months"
,case
when cont_all.CONTRACT_EFFECTIVE_DATE <='&end_date' then 'Contract'
when cont_all.CONTRACT_EFFECTIVE_DATE > '&end_date' then 'No Contract'
when cont_all.CONTRACT_EXPIRATION_DATE <= '&end_date' then 'No Contract'
when cont_all.CONTRACT_EXPIRATION_DATE > '&end_date' then 'Contract'
when cont_all.CONTRACT_EFFECTIVE_DATE is null then 'No Contract'
else 'Wrong'
end as "Contract Indicator"
-- ,case
-- when
-- round(sum(i.INVOICE_AMOUNT)) > 50000 and
-- (cont_all.CONTRACT_EFFECTIVE_DATE > '&end_date'
-- or cont_all.CONTRACT_EXPIRATION_DATE <= '&end_date'
-- or cont_all.CONTRACT_EFFECTIVE_DATE is null)
-- then 'Over 50k and no Contract'
-- else 'Contract or No Contract with spend below 50k'
-- end as "Contract Needed?"
,t.NAME "Terms"
,TO_CHAR(TO_DATE('&end_date', 'DD-MON-YYYY'), 'Mon YY') Month
from
AP.AP_SUPPLIERS v
join AP.AP_SUPPLIER_SITES_ALL s on v.VENDOR_ID=s.VENDOR_ID
join apps.HR_ALL_ORGANIZATION_UNITS o on s.ORG_ID=o.ORGANIZATION_ID
left join AP.AP_INVOICES_ALL i on s.VENDOR_SITE_ID=i.VENDOR_SITE_ID
left join AP_TERMS_TL t on s.TERMS_ID=t.TERM_ID
left join APPS.OKC_REP_CONTRACT_PARTIES cont on v.VENDOR_ID=cont.PARTY_ID
left join APPS.OKC_REP_CONTRACTS_ALL cont_all on cont.CONTRACT_ID=cont_all.CONTRACT_ID
where
((v.end_date_active is null or v.end_date_active > '&end_date') and (s.inactive_date is null or s.inactive_date > '&end_date'))
and v.CREATION_DATE <= '&end_date'
and s.ORG_ID in ('324','288','325','285','301','296','302','294','327','305','304','298','303','297','299','300','295','309','307','316','312','314','317','313','318','315','320','319','322','323','326','321','308','310','311','306')
and v.SEGMENT1 = 259456
and i.CREATION_DATE between add_months('&end_date', -12) and '&end_date'
and i.CANCELLED_DATE is null
group by
v.SEGMENT1
,v.VENDOR_NAME
,s.VENDOR_SITE_CODE
,case
when s.ORG_ID in ('285', '296', '294', '327', '304', '297', '295', '312', '313', '315', '319', '322', '321', '306') then 'Fleet'
else 'Non-Fleet'
end
,case
when s.ORG_ID in ('288','325','285') then 'Belgium'
when s.ORG_ID in ('301','296','302','294') then 'Germany'
when s.ORG_ID in ('327','305','304') then 'Spain'
when s.ORG_ID in ('298','303','297','299','300','295') then 'France'
when s.ORG_ID in ('309','307') then 'Ireland'
when s.ORG_ID in ('316','312','314','317','313') then 'Italy'
when s.ORG_ID in ('318','315') then 'Luxembourg'
when s.ORG_ID in ('318','315') then 'Monaco'
when s.ORG_ID in ('322','323','324','326','321') then 'Netherlands'
when s.ORG_ID in ('308','310','311','306') then 'United Kingdom'
else 'Error'
end
,o.NAME
,case
when cont_all.CONTRACT_EFFECTIVE_DATE <='&end_date' then 'Contract'
when cont_all.CONTRACT_EFFECTIVE_DATE > '&end_date' then 'No Contract'
when cont_all.CONTRACT_EXPIRATION_DATE <= '&end_date' then 'No Contract'
when cont_all.CONTRACT_EXPIRATION_DATE > '&end_date' then 'Contract'
when cont_all.CONTRACT_EFFECTIVE_DATE is null then 'No Contract'
else 'Wrong'
end
-- ,case
-- when
-- (round(sum(i.INVOICE_AMOUNT)) > 50000
-- and
-- (cont_all.CONTRACT_EFFECTIVE_DATE > '&end_date'
-- or cont_all.CONTRACT_EXPIRATION_DATE <= '&end_date'
-- or cont_all.CONTRACT_EFFECTIVE_DATE is null) )
-- then 'Over 50k and no Contract'
-- else 'Contract or No Contract with spend below 50k'
-- end
,t.NAME
,TO_CHAR(TO_DATE('&end_date', 'DD-MON-YYYY'), 'Mon YY')
这是您的简化示例
create table tab as
select
1 SEGMENT1,
sysdate + rownum as CONTRACT_EFFECTIVE_DATE, rownum INVOICE_AMOUNT from dual
connect by level <= 10;
select
SEGMENT1,
case when sum(INVOICE_AMOUNT) > 50 and CONTRACT_EFFECTIVE_DATE > DATE'2020-01-01' then 'OK' else 'NOK' end as col1
from tab
group by SEGMENT1;
这当然会导致 ORA-00979: not a GROUP BY expression
因为你 不 group by
CONTRACT_EFFECTIVE_DATE
但是添加 CONTRACT_EFFECTIVE_DATE
很可能不是您想要的。
我想你需要把过滤条件 放入 聚合函数中,像这样 - 所以你只聚合 INVOICE_AMOUNT
如果条件是完整的并进行比较结果与阈值
select
SEGMENT1,
case when
sum(case when CONTRACT_EFFECTIVE_DATE > DATE'2020-01-01'then INVOICE_AMOUNT end) > 50
then 'OK' else 'NOK' end as col1
from tab
group by SEGMENT1;