我有一个可以运行的查询,它生成如下行:
ID | category | property_A | property_B
----+----------+------------+------------
1 | X | tall | old
2 | X | short | old
3 | X | tall | old
4 | X | short | young
5 | Y | short | old
6 | Y | short | old
7 | Y | tall | old
我想为每个category
和property_B
找到最常见的property_A
,然后将其放入另一个表格供以后使用。所以在这里我想知道,在X类中,老年人往往很高,年轻人很矮,而在Y类,老年人往往很矮。
每列的域都是有限的,而且不是太大 - 有200个类别,还有十几个属性_A和property_B。所以我可以在我的客户端上编写一个愚蠢的脚本,它会查询数据库200 * 12 * 12次,进行有限的查询,但这看起来一定是错误的方法,而且浪费,因为生成这个表是很昂贵的然后扔掉大部分。
但我甚至不知道要查找哪些单词以找到正确的方法:“sql find related rows”显示了如何查找整数相关性,但我对整数不感兴趣。那我该怎么做呢?
答案 0 :(得分:3)
您可以通过聚合和窗口/分析功能轻松完成此操作。你想要排名第一的人数。以下返回最受欢迎的A:
select category, property_b, property_a as MostPopularA
from (select category, property_b, property_a, count(*) as cnt,
row_number() over (partition by category, property_b order by count(*) desc) as seqnum
from table t
group by category, property_b, property_a
) t
where seqnum = 1;
如果您想在有平局时获取所有值,请使用dense_rank()
代替row_number()
。
答案 1 :(得分:2)
我建议使用GROUP BY
和DISTINCT ON
的组合,这在Postgres中更快/更简单/更优雅:
SELECT DISTINCT ON (category, property_b)
category, property_b, property_a, count(*) AS ct
FROM tbl
GROUP BY category, property_b, property_a
ORDER BY category, property_b, ct DESC;
返回:
category | property_b | property_a | ct
---------+------------+------------+----
X | old | tall | 2
X | young | short | 1
Y | old | short | 2
如果多个对等体绑定最常见的值,则只返回一个任意选择。
这适用于没有子查询的单个查询级别,因为在GROUP BY
步骤之前应用了聚合(DISTINCT
)。 DISTINCT ON
的详细说明:
Select first row in each GROUP BY group?