从具有多个Group_BY的多个JOIN表中选择多个计数

时间:2016-05-16 16:44:51

标签: sql postgresql

我有以下SQL获得正确的结果:

SELECT 
companies.name as company_name, 
locations.country_code as location,
ad_messages.ad_template_name as creative, 
impressions.width as width,
impressions.height as height, 
count('impressions.id') as impressions 
FROM "impressions" 
INNER JOIN "ad_messages" ON "ad_messages"."id" = "impressions"."ad_message_id" 
INNER JOIN "visitors" ON "visitors"."id" = "ad_messages"."visitor_id" 
INNER JOIN "companies" ON "companies"."visitor_id" = "visitors"."id" 
INNER JOIN "locations" ON "locations"."visitor_id" = "visitors"."id" 
WHERE (visitors.user_id = 171) 
 AND (impressions.created_at >= '2016-03-17 16:17:20.241276' 
 AND impressions.created_at <= '2016-05-16 16:17:20.241336') 
 GROUP BY 
 companies.name, 
 locations.country_code,
 ad_messages.ad_template_name, 
 impressions.width, 
 impressions.height 
 ORDER BY 
 companies.name, 
 locations.country_code,
 ad_messages.ad_template_name, 
 impressions.width, 
 impressions.height

我将结果(展示次数)分组并对sub_name,sub_name和ad_messages进行了分组。

Impressions only Result

我可以重复点击过程并获得不同过滤器分组和分组的结果(点击次数),如下所示:

SELECT 
companies.name as company_name, 
locations.country_code as location,
ad_messages.ad_template_name as creative, 
ad_clicks.width as width,
ad_clicks.height as height, 
count('ad_clicks.id') as ad_clicks
FROM "ad_messages" 
INNER JOIN "ad_clicks" ON "ad_clicks"."ad_message_id" = "ad_messages"."id"
INNER JOIN "visitors" ON "visitors"."id" = "ad_messages"."visitor_id" 
INNER JOIN "companies" ON "companies"."visitor_id" = "visitors"."id" 
INNER JOIN "locations" ON "locations"."visitor_id" = "visitors"."id"
WHERE (visitors.user_id = 171) 
 AND (ad_clicks.created_at >= '2016-03-17 16:17:20.241276' 
 AND ad_clicks.created_at <= '2016-05-16 16:17:20.241336') 
 GROUP BY 
 companies.name, 
 locations.country_code,
 ad_messages.ad_template_name, 
 ad_clicks.width, 
 ad_clicks.height
  ORDER BY 
 companies.name, 
 locations.country_code,
 ad_messages.ad_template_name, 
 ad_clicks.width, 
 ad_clicks.height

但是 - 我想在一个查询中结合展示次数和点击次数,我试过了:

SELECT 
companies.name as company_name, 
locations.country_code as location,
ad_messages.ad_template_name as creative, 
impressions.width as width,
impressions.height as height, 
ad_clicks.width as click_width,
ad_clicks.height as click_height, 
count('impressions.id') as impressions,
count('ad_clicks.id') as clicks
FROM "ad_messages" 
INNER JOIN "impressions" ON "impressions"."ad_message_id" = "ad_messages"."id"
INNER JOIN "visitors" ON "visitors"."id" = "ad_messages"."visitor_id" 
INNER JOIN "companies" ON "companies"."visitor_id" = "visitors"."id" 
INNER JOIN "locations" ON "locations"."visitor_id" = "visitors"."id"
LEFT JOIN "ad_clicks" ON "ad_clicks"."ad_message_id" = "ad_messages"."id" 
WHERE (visitors.user_id = 171) 
 AND (impressions.created_at >= '2016-03-17 16:17:20.241276' 
 AND impressions.created_at <= '2016-05-16 16:17:20.241336') 
 GROUP BY 
 companies.name, 
 locations.country_code,
 ad_messages.ad_template_name, 
 impressions.width, 
 impressions.height,
 ad_clicks.width, 
 ad_clicks.height 

这给了我完全错误的结果! count(impression)和count(ad_clicks)具有相同的值。有什么方法可以从一个SQL获得正确的计数吗?

感谢任何帮助。谢谢!

1 个答案:

答案 0 :(得分:1)

您可以像这样使用count(col_name) over (partition by .... order by ...),使用select distinct代替group by。并尝试使用alias代替full_table_name

SELECT DISTINCT
    companies.name as company_name, 
    locations.country_code as location,
    ad_messages.ad_template_name as creative, 
    impressions.width as width,
    impressions.height as height, 
    ad_clicks.width as click_width,
    ad_clicks.height as click_height, 
    count('impressions.id') over (partition by companies.name, locations.country_code, 
            ad_messages.ad_template_name, impressions.width, impressions.height 
            order by    companies.name, locations.country_code, ad_messages.ad_template_name, 
            impressions.width, impressions.height)  as impressions,
    count('ad_clicks.id') over (partition by companies.name, locations.country_code, 
            ad_messages.ad_template_name, ad_clicks.width, ad_clicks.height 
            order by companies.name, locations.country_code, ad_messages.ad_template_name, 
            ad_clicks.width, ad_clicks.height ) as clicks
FROM "ad_messages" 
INNER JOIN "impressions" ON "impressions"."ad_message_id" = "ad_messages"."id"
INNER JOIN "visitors" ON "visitors"."id" = "ad_messages"."visitor_id" 
INNER JOIN "companies" ON "companies"."visitor_id" = "visitors"."id" 
INNER JOIN "locations" ON "locations"."visitor_id" = "visitors"."id"
LEFT JOIN "ad_clicks" ON "ad_clicks"."ad_message_id" = "ad_messages"."id" 
WHERE (visitors.user_id = 171) 
     AND (impressions.created_at >= '2016-03-17 16:17:20.241276' 
     AND impressions.created_at <= '2016-05-16 16:17:20.241336') 
ORDER BY 
    companies.name, 
    locations.country_code,
    ad_messages.ad_template_name, 
    impressions.width, 
    impressions.height,
    ad_clicks.width, 
    ad_clicks.height 

SQLFIDDLE

中的测试