[英]Case Expressions in Oracle SQL (Pentaho Report Designer)
我需要拉长客户的年龄,并将结果分为几类(18-21、22-35、36-50等)。
使用基于Oracle的Pentaho Report Designer。
我可以提取特定年龄段的计数,但希望该计数反映年龄段,而不是单个年龄段。 尝试通过case语句完成此操作,但会不断出错。
对Pentaho / Oracle来说是SQL的新手,这是该网站的新手,对SQL的影响最小。
--SQL的年龄和计数。
SELECT COUNT(*), "CLIENT_TABLE"."AGE"
FROM "CLIENT_TABLE"
GROUP BY "CLIENT_TABLE"."AGE"
ORDER BY "CLIENT_TABLE"."AGE"
-这是我的CASE表达。
CASE
WHEN "CLIENT_TABLE"."AGE" < 18 THEN 'Under 18'
WHEN "CLIENT_TABLE"."AGE" > 18 AND <= 21 THEN '19 - 21'
WHEN "CLIENT_TABLE"."AGE" > 21 AND <= 35 THEN '22 - 35'
END AS Age
我将CASE表达式放在SELECT和WHERE子句中,但是不断收到这两个错误消息...“在期望的位置找不到FROM关键字”和“缺少表达式”。
更新的代码会产生错误“不是按表达式分组”。
SELECT COUNT(*),
(CASE
WHEN "CLIENT_TABLE"."AGE" < 18 THEN 'Under 18'
WHEN "CLIENT_TABLE"."AGE" <= 21 THEN '18 - 21'
WHEN "CLIENT_TABLE"."AGE" <= 35 THEN '22 - 35'
WHEN "CLIENT_TABLE"."AGE" <= 50 THEN '36 - 50'
WHEN "CLIENT_TABLE"."AGE" <= 64 THEN '51 - 64'
WHEN "CLIENT_TABLE"."AGE" >= 65 THEN '65+'
END) AS AgeRange
FROM "CLIENT_TABLE"
GROUP BY (CASE
WHEN "CLIENT_TABLE"."AGE" < 18 THEN 'Under 18'
WHEN "CLIENT_TABLE"."AGE" <= 21 THEN '18 - 21'
WHEN "CLIENT_TABLE"."AGE" <= 35 THEN '22 - 35'
WHEN "CLIENT_TABLE"."AGE" <= 50 THEN '36 - 50'
WHEN "CLIENT_TABLE"."AGE" <= 64 THEN '51 - 64'
WHEN "CLIENT_TABLE"."AGE" >= 65 THEN '65+'
END)
ORDER BY "CLIENT_TABLE"."AGE"
我想你要:
SELECT COUNT(*),
(CASE WHEN "CLIENT_TABLE"."AGE" < 18 THEN 'Under 18'
WHEN "CLIENT_TABLE"."AGE" <= 21 THEN '19 - 21'
WHEN "CLIENT_TABLE"."AGE" <= 35 THEN '22 - 35'
END) AS Age
FROM "CLIENT_TABLE"
GROUP BY (CASE WHEN "CLIENT_TABLE"."AGE" < 18 THEN 'Under 18'
WHEN "CLIENT_TABLE"."AGE" <= 21 THEN '19 - 21'
WHEN "CLIENT_TABLE"."AGE" <= 35 THEN '22 - 35'
END)
ORDER BY "CLIENT_TABLE"."AGE"
笔记:
GROUP BY
重复该表达式。 case
表达。 条件是按顺序评估的。 '19 - 21'
组。 将它们包括在某个位置似乎比将它们放入NULL
组更合适。 基于"CLIENT_TABLE"."AGE"
的回答,您的“更新代码”得到“ ORA-00979:不是GROUP BY表达式”,因为您正尝试通过"CLIENT_TABLE"."AGE"
进行排序"CLIENT_TABLE"."AGE"
-该列不在GROUP BY
子句中。 您可能想要:
ORDER BY MIN("CLIENT_TABLE"."AGE")
但是,这只会显示具有匹配数据的范围。 如果要查看所有范围,包括零计数,则可以将范围生成为内联视图或CTE,并以外部联接方式生成真实数据,例如:
WITH "RANGES" ("MIN_AGE", "MAX_AGE", "LABEL") AS (
SELECT 0, 17, 'Under 18' FROM "DUAL"
UNION ALL
SELECT 18, 21, '18 - 21' FROM "DUAL"
UNION ALL
SELECT 22, 35, '22 - 35' FROM "DUAL"
UNION ALL
SELECT 36, 50, '36 - 50' FROM "DUAL"
UNION ALL
SELECT 51, 64, '51 - 64' FROM "DUAL"
UNION ALL
SELECT 65, NULL, '65+' FROM "DUAL"
)
SELECT COUNT("CLIENT_TABLE"."AGE"),
"RANGES"."LABEL" AS AgeRange
FROM "RANGES"
LEFT JOIN "CLIENT_TABLE"
ON "CLIENT_TABLE"."AGE" >= "RANGES"."MIN_AGE"
AND ("RANGES"."MAX_AGE" IS NULL OR "CLIENT_TABLE"."AGE" <= "RANGES"."MAX_AGE")
GROUP BY "RANGES"."MIN_AGE", "RANGES"."LABEL"
ORDER BY "RANGES"."MIN_AGE"
您可以从最小/最大年龄生成标签,甚至可以从最小年龄生成标签(使用潜在客户来找到最大年龄),还可以探索其他变体。
(我假设您使用大写标识符和带引号的标识符是有原因的,这可能是您的报表工具的要求-我知道有些奇怪的事情确实需要它们;但是从Oracle的角度来看,不需要双引号,而且我个人查找小写或混合代码(也许是关键字大写)更易于阅读。您可能还希望使用表别名。)
对于空值,我应该在CASE中有一个ELSE。
COUNT()
忽略空值,因此,如果COUNT("CLIENT_TABLE"."AGE")
空值,则将返回零。 您将需要计算表中所有非空列; 并且在RANGES
CTE中需要另一个虚拟行,并且需要修改逻辑以包括未设置年龄的行; 例如:
with ranges (min_age, max_age, label) as (
select 0, 17, 'Under 18' from dual
union all
select 18, 21, '18 - 21' from dual
union all
select 22, 35, '22 - 35' from dual
union all
select 36, 50, '36 - 50' from dual
union all
select 51, 64, '51 - 64' from dual
union all
select 65, null, '65+' from dual
union all
select null, null, 'Unknown' from dual
)
select count(client_table.id), -- count any not-null column from this table
ranges.label as agerange
from ranges
left join client_table
on ((ranges.min_age is null and client_table.age is null)
or client_table.age >= ranges.min_age)
and (ranges.max_age is null or client_table.age <= ranges.max_age)
group by ranges.min_age, ranges.label
order by ranges.min_age
让我们简化一下:
SELECT AGERANGE, COUNT(1) AS CNT FROM
SELECT (CASE
WHEN "CLIENT_TABLE"."AGE" < 18 THEN 'Under 18'
WHEN "CLIENT_TABLE"."AGE" <= 21 THEN '18 - 21'
WHEN "CLIENT_TABLE"."AGE" <= 35 THEN '22 - 35'
WHEN "CLIENT_TABLE"."AGE" <= 50 THEN '36 - 50'
WHEN "CLIENT_TABLE"."AGE" <= 64 THEN '51 - 64'
WHEN "CLIENT_TABLE"."AGE" >= 65 THEN '65+'
END) AS AgeRange
FROM "CLIENT_TABLE")
GROUP BY AGERANGE
ORDER BY CASE AGERANGE
WHEN 'Under 18' THEN 1
WHEN '18 - 21' THEN 2
WHEN '22 - 35' THEN 3
WHEN '36 - 50' THEN 4
WHEN '51 - 64' THEN 5
WHEN '65+' THEN 6
ELSE 7 END;
干杯!!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.