sql - 使用不带聚合的 GROUP BY 来检索不同的 "best"结果的替代方法

标签 sql group-by aggregation

我正在尝试从 SQL 表中检索“最佳”可能条目。

考虑一个包含电视节目的表: id、标题、剧集、is_hidef、is_verified 例如:

id title         ep hidef verified
1  The Simpsons  1  True  False
2  The Simpsons  1  True  True
3  The Simpsons  1  True  True
4  The Simpsons  2  False False
5  The Simpsons  2  True  False

单个标题和剧集可能有重复的行,这些行的 bool 字段值可能不同,也可能没有。可能还有更多列包含附加信息,但这并不重要。

我想要一个结果集,为我提供每集的最佳行(因此 is_hidef 和 is_verified 在可能的情况下都是“true”)。对于被视为“相等”的行,我想要最新的行(自然排序,或按任意日期时间列排序)。

3  The Simpsons  1  True  True
5  The Simpsons  2  True  False

过去我会使用以下查询:

SELECT * FROM shows WHERE title='The Simpsons' GROUP BY episode ORDER BY is_hidef, is_verified

这适用于 MySQL 和 SQLite,但违反了 SQL 规范(GROUP BY 需要聚合等)。我真的没有兴趣再次听到为什么 MySQL 如此糟糕地允许这样做;但我非常有兴趣找到一种也适用于其他引擎的替代解决方案(如果您能给我它的 django ORM 代码,那就加分了)。

谢谢=)

最佳答案

在某种程度上与 Andomar 类似,但这个确实有效。

select C.*
FROM
(
    select min(ID) minid
    from (
        select distinct title, ep, max(hidef*1 + verified*1) ord
        from tbl
        group by title, ep) a
    inner join tbl b on b.title=a.title and b.ep=a.ep and b.hidef*1 + b.verified*1 = a.ord
    group by a.title, a.ep, a.ord
) D inner join tbl C on D.minid = C.id

第一级仲裁使用 *1 将位 (SQL Server) 或 MySQL bool 值转换为整数值,然后添加列以生成“最佳”值。您可以给它们重量,例如如果 hidef > verify,则使用 hidef*2 + verify*1 可以生成 3,2,1 或 0。

第二级在“最佳”场景中查找并提取最小 ID(或其他一些决胜列)。这对于将多匹配结果集减少到只有一条记录至关重要。

在这种特殊情况(表模式)中,外部选择使用直接键来检索匹配的记录。

关于sql - 使用不带聚合的 GROUP BY 来检索不同的 "best"结果的替代方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4710406/

相关文章:

MySQL - GROUP_CONCAT 返回重复数据,不能使用 DISTINCT

python pandas 将数据帧乘以向量化方式中随类别变化的权重

Mysql 从多个表中选择 sum() 和 group by

sql - 计数表中值连续出现的次数

hadoop - RAMdisk 中的 HBase 速度较慢

elasticsearch - Elasticsearch 聚合始于

php - mysql 的 FOR UPDATE/LOCK IN SHARE MODE 也会锁定 future 的行吗?

mysql - 如何修复过程 SQL 中的错误?

sql - 使用postgresql格式化时间戳和数字的两个问题

MySQL GROUP BY 每组返回多行