sql - 如何检查所有聚合行中的某个值?

标签 sql oracle reporting analytics aggregate-functions

假设我有三个表:user , groupxref ,一个为他们提供多对多 RI 的表。

我可能想查看每个用户所属的组:

select
    user.user_id,
    user.user_name,
    count(*) as group_count
from
    user
        inner join xref on user.user_id = xref.user_id
        inner join group on group.group_id = xref.group_id
group by user.user_id, user.user_name

到目前为止一切正常。但是,如果我想要一些额外的信息怎么办?我正在报告,我想知道每个用户是开发人员还是内容管理员。现在,出现了一种反模式:

select
    user.user_id,
    user.user_name,
    count(*) as group_count,
    max( case group.group_name when 'Developers' then 'Y' else null end )
        as is_dev
    max( case group.group_name when 'Content Management' then 'Y' else null end )
        as is_cm
from
    user
        inner join xref on user.user_id = xref.user_id
        inner join group on group.group_id = xref.group_id
group by user.user_id, user.user_name

这有效,并产生了预期的结果,但感觉非常错误。我问Oracle的是:

"For each user, show me how many groups they're in. Also, for all group names per user, show me if 'Developers' is one of the values."

实际上要问的是:

"For each user, show me how many groups they're in. Also, for all group names per user, show me the highest value produced by this case expression."

这是一种反模式的原因是我基本上依赖于这样一个事实:Y 碰巧null 上方“冒泡”当使用 max() 进行评估时。如果有人想要复制或扩充此查询,他们可能很容易忘记反模式,并意外地将返回值更改为不使用相同的不直观巧合的值。

基本上,我希望编写的查询是这样的:

select
    user.user_id,
    user.user_name,
    count(*) as group_count,
    any(group.group_name, 'Developers', 'Y', null) as is_dev,
    any(group.group_name, 'Content Management', 'Y', null) as is_cm
from
    user
        inner join xref on user.user_id = xref.user_id
        inner join group on group.group_id = xref.group_id
group by user.user_id, user.user_name

我一直在寻找选择,似乎有一些潜力:

  • first_value可以工作,但我不知道如何限制相应的 partition窗口向右行。
  • 具有 over 的分析函数子句可能有效,但我确实想要折叠分组所依据的列,所以它似乎不是一个完美的选择。
  • 令人愤怒的是,似乎有一个any功能记录here ,但它仅存在于一种名为 Oracle OLAP DML 的神秘方言中,我认为在 10g 上仅使用 SQL 无法访问它。但是,它似乎完全符合我的要求。

这就是我所得到的。有什么想法吗?

我认识到有两个非常简单的想法,“在代码中执行”或“在 PL/SQL 中执行”,但这是作弊。 :-)

最佳答案

我会从 MAX 切换到 SUM(使用 1 而不是 Y),因此您会说“计算此人所在组名称为 Developers 的组数”。

该模式类似于“计算购买值(value)超过 30 美元的销售数量”。

如果需要,您可以添加另一个表达式来表示“如果计数大于零,则‘是’此人是开发人员”。非常明确,但可能没有必要。

关于sql - 如何检查所有聚合行中的某个值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3731102/

相关文章:

sql - oracle 行计数到 shell 脚本变量

postgresql - pentaho CDE,来自 PostgreSQL 的报表设计器 justify_interval 查询

mysql - 开放网络分析是否允许我根据数据库中存储的数据为网络应用程序创建报告?

php - Mysql 将资源 #16 插入数据库表

java - SQLite删除列: Using temporary table vs Renaming using ALTER TABLE的方法

python - 使用 JSON 数据填充 SQLite 表,得到 : sqlite3. OperationalError: near "x": syntax error

java - Spring Batch 作业参数限制为 250 个字符?

sql - 是否可以使用 SQL 更新 CLOB 内的数据?

java - 数据集中的行数问题

mysql - 如何在具有复合键列表的表上执行 SELECT?