sql - 获取 GROUP BY 后的行数

标签 sql postgresql activerecord relational-division

这是我在 Ruby on Rails 项目中使用的代码,用于查找具有 便利设施ids 为 48、49 和 50 的residences . 它们通过连接与一个 has_many 相连。

id_list = [48, 49, 50]
Residence.joins(:listed_amenities).
          where(listed_amenities: {amenity_id: id_list}).
          group('residences.id').
          having("count(listed_amenities.*) = ?", id_list.size)

生成的 SQL:

SELECT "residences".*
FROM "residences"
INNER JOIN "listed_amenities" ON "listed_amenities"."residence_id" = "residences"."id"
WHERE "listed_amenities"."amenity_id" IN (48, 49, 50)
GROUP BY residences.id
HAVING count(listed_amenities.*) = 3

我对从该查询中得到的 residences 的数量感兴趣。有没有办法添加 count 或其他东西让数据库进行计算?我不想在 Ruby 中浪费计算能力。添加 .count 方法不起作用。结果为 {528747=>3, 529004=>3, 529058=>3}

最佳答案

如果您的设计强制执行参照完整性,则您根本不必为此目的加入表residences。还假设 (residence_id, amenity_id) 上的 UNIQUEPK 约束(否则您需要不同的查询!)

最佳查询取决于您确切的需求。

使用窗口函数,您可以甚至在单个查询级别执行此操作:

SELECT count(*) OVER () AS ct
FROM   listed_amenities
WHERE  amenity_id IN (48, 49, 50)
GROUP  BY residence_id
HAVING count(*) = 3
LIMIT  1;

此窗口函数将总计数附加到每一行而不聚合行。考虑 SELECT 查询中的事件序列:

因此,您可以使用类似的查询来返回所有符合条件的 ID(甚至整行)并将计数附加到每一行(冗余):

SELECT residence_id, count(*) OVER () AS ct
FROM   listed_amenities
WHERE  amenity_id IN (48, 49, 50)
GROUP  BY residence_id
HAVING count(*) = 3;

但最好使用子查询,这通常要便宜得多:

SELECT count(*) AS ct
FROM  (
   SELECT 1
   FROM   listed_amenities
   WHERE  amenity_id IN (48, 49, 50)
   GROUP  BY residence_id 
   HAVING count(*) = 3
   ) sub;

可以同时返回一个 ID 数组(与上面的集合相反),几乎不会增加任何成本:

SELECT array_agg(residence_id ) AS ids, count(*) AS ct
FROM  (
   SELECT residence_id 
   FROM   listed_amenities
   WHERE  amenity_id IN (48, 49, 50)
   GROUP  BY residence_id
   HAVING count(*) = 3
   ) sub;

还有许多其他变体,您必须阐明预期结果。就像这个:

SELECT count(*) AS ct
FROM   listed_amenities l1
JOIN   listed_amenities l2 USING (residence_id)
JOIN   listed_amenities l3 USING (residence_id)
WHERE  l1.amenity_id = 48
AND    l2.amenity_id = 49
AND    l2.amenity_id = 50;

基本上这是关系除法的情况。我们在这里汇集了一系列技术:

关于sql - 获取 GROUP BY 后的行数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32704765/

相关文章:

SQL查询根据其他字段统计有多少个值

sql - 在不删除关联序列的情况下删除 PostgreSQL 中的表

sql - 如何加快 PostgreSQL 中的插入性能

mysql - VARCHAR 上的内部连接

python - 如何在Python中读取postgresql转储文件

ruby-on-rails - rails,如何合并两个 ActiveRecord 查询结果

Python Pony ORM 一次插入多个值

postgresql - 在 mac os 中找不到 PostGIS 扩展(安装在不同的目录中)和 $libdir/postgis-2.3

php - Codeigniter 3.1.0 Active Record 更新查询既不出错也不更新数据库

sql - 显示消息数组中的最后一条消息