繁体   English   中英

Oracle SQL中的案例表达式(Pentaho Report Designer)

[英]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"

笔记:

  • 在Oracle中,您需要在GROUP BY重复该表达式。
  • 我简化了逻辑在的条件case表达。 条件是按顺序评估的。
  • 这样一来,包括了18岁的孩子-现在属于“ '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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM