2012-11-14 59 views
1

对不起,我不确定如何解释这个,我是新一代的SQL技能已经退化的人之一感谢有效的记录模式!得到一个孩子关系的计数和一个孩子的计数

基本上我有三个表中的PostgreSQL

客户端(一个客户机有许多地图) - ID

地图(地图有一个客户端和很多层) - ID - CLIENT_ID

层(层有一个地图) - ID - map_id

我想编写一个SQL查询返回Cliend.id以及客户端有多少地图以及客户端在所有地图上的总层数。

这可能与一个单一的查询?速度并不关心,因为这仅仅是为了分析目的,所以很少运行。

回答

2

我会为此使用一对子查询。喜欢的东西:

SELECT 
    id, 
    (
     SELECT count(map.id) 
     FROM map 
     WHERE map.client_id = client.id 
    ) AS n_maps, 
    (
     SELECT count(layer.id) 
     FROM map INNER JOIN layer ON (layer.map_id = map.id) 
     WHERE map.client_id = client.id 
    ) AS n_layers 
FROM client; 
+0

感谢克雷格,几乎对我的作品,但n_laye rs似乎返回最后一张地图中的图层数量,而不是所有的地图总和 – ChrisInCambo

+0

@ChrisInCambo奇怪的是,它不应该 - 除非我错过了一些非常明显的东西,当然这并不是前所未闻的。这是一个相当标准的相关子查询。一些示例数据可能有助于('CREATE TABLE'和'INSERT's)在SQLFiddle上;我宁愿不需要虚拟一个模型来进行测试。 –

+0

是的,我忘了地图和图层表之间有一个group_layer表。 – ChrisInCambo

1

我不喜欢这样,一个SQL查询的客户端模型的方法中:

def self.statistics 
    Client.select(" 
      clients.id AS client_id, 
      COUNT(DISTINCT(maps.id)) AS total_maps, 
      COUNT(layers.id) AS total_layers") 
    .joins(maps: :layers) 
    .group("clients.id") 
end 

为了这个工作,你需要之间声明的协会你的模型(客户的has_many:地图,地图的has_many:层)

你可以去depper中的ActiveRecord的查询界面here

+0

在地图ID上使用'DISTINCT'可能比我发布的方法更好,但当然我会'解析ANALYZE'来查明。 +1 –