我有一个相对较大的(如在> 10 ^ 6条目中)称为“东西”的表,它表示可定位的对象,例如,国家,地区,城市,街道等。它们被用作具有固定深度的对象树,因此表格结构如下所示:
id
name
type
continent_id
country_id
city_id
area_id
street_id
etc.
“事物”内的关联是1:n,即街道或地区总是属于定义的城市和国家(不是两个或没有);例如,city_id列包含该城市内所有对象的“城市”事物的id。 “类型”列包含事物类型(街道,城市等)作为字符串。
此表在另一个表“actions”中被引用为“thing_id”。我正在尝试生成一个操作位置统计信息表,显示给定位置的活动和非活动操作数。一个简单的JOIN,如
SELECT count(nullif(actions.active, 1)) AS icount, count(nullif(actions.active, 0)) AS acount, things.name AS name, things.id AS thing_id, things.city_id AS city_id FROM "actions" LEFT JOIN things ON actions.thing_id = things.id WHERE UPPER(substring(things.name, 1, 1)) = UPPER('A') AND actions.datetime_at BETWEEN '2012-09-26 19:52:14' AND '2012-10-26 22:00:00' GROUP BY things.name, things.id ORDER BY things.name
将为我提供一个“事物”列表(以“A”开头),其中包含与其相关的操作及其活动和非活动计数,如下所示:
icount | acount | name | thing_id | city_id
------------------------------------------------------------------
0 5 Brooklyn, New York City | 25 | 23
1 0 Manhattan, New York City | 24 | 23
3 2 New York City | 23 | 23
现在我想
icount | acount | name | thing_id | city_id ------------------------------------------------------------------ 4 7 New York City | 23 | 23
我不需要这个表中的thing_id(因为它不会是唯一的),但是因为我确实需要城市的名字(用于显示),所以也可能同样容易输出ID,然后我不必在我的代码中进行更改。
我如何修改上述查询才能实现此目的?如果可能的话,我想避免额外访问数据库,以及高级SQL功能,如过程,触发器,视图和临时表。
我在Rails 3.0.14上使用Postgres 8.3和Ruby 1.9.3(在Mac OS X 10.7.4上)。
谢谢! :)
答案 0 :(得分:2)
您需要在独立子查询中计算城市中所有事物的操作,然后加入一组有限的事物:
SELECT c.icount
,c.acount
,t.name
,t.id AS thing_id
,t.city_id
FROM (
SELECT t.city_id
,count(nullif(a.active, 1)) AS icount
,sum(a.active) AS acount
FROM things t
LEFT JOIN actions a ON a.thing_id = t.id
WHERE t.city_id = 23 -- to restrict results to one city
GROUP BY t.city_id
) c -- counts per city
JOIN things t USING (city_id)
WHERE t.name ILIKE 'A%'
AND t.datetime_at BETWEEN '2012-09-26 19:52:14'
AND '2012-10-26 22:00:00'
ORDER BY t.name, t.id;
我还简化了查询中的许多其他内容,并使用了表别名来使其更易于阅读。