2016-05-16 59 views
0

我有以下SQL得到正确的结果表:选择从多个多计数JOIN具有多个Group_BYs

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 

我得到的结果(展示次数)分组并subgrouped即company_name,地点和ad_messages。

Impressions only Result

我可以重复此过程的点击,并得到结果(点击数)进行分组,并通过不同的过滤器subgrouped像这样:

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 

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

任何帮助表示赞赏。谢谢!

回答

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

的测试