从具有条件的多个表中按计数分组
Group By Count from Multiple Tables with conditions
我有 3 个不同的 table,国家、城市和客户。表格如下:
国家table:
id country_name
1 UK
2 US
3 Brazil
:
n Canada
城市table
id city_name postal_code country_id
1 London 30090 1
2 Dallas 20909 2
3 Rio 29090 3
4 Atlanta 30318 2
:
n Vancouver 32230 n
顾客table
id customer_name city_id
1 John 1
2 Pete 3
3 Dave 2
4 May 2
5 Chuck 4
6 Sam 3
7 Henry 3
***country.id 是引用 city.country_id,city.id 是引用 customer.city_id
我想写一个查询,可以提取国家名称、城市名称和相关城市的客户数量。但是在一个条件下,查询将 return 所有城市的客户数量超过所有城市的平均客户数量
它看起来像下面这样,这是正确的输出
UK London 2
Brazil Rio 3
但我一直得到这个输出,这是不正确的
UK London 2
US Dallas 2
US Atlanta 1
Brazil Rio 3
我写了一个 SQL 查询,但它没有给我想要的结果
SELECT country.country_name, city.city_name, COUNT(customer.city_id) from country
JOIN city on country.id = city.country_id
JOIN customer on city.id = customer.city_id
Group by city_name,country.country_name;
我想知道如何执行此操作并修复我的代码?
您需要将查询嵌套到子查询中,以便您可以取计数的平均值并将当前计数与其进行比较。如果您使用的是支持 CTE 的 SQL,您可以使用一个
WITH cnts AS (
SELECT country.country_name, city.city_name, COUNT(customer.city_id) AS cnt
FROM country
JOIN city on country.id = city.country_id
JOIN customer on city.id = customer.city_id
GROUP BY city_name,country.country_name
)
SELECT *
FROM cnts
WHERE cnt > (SELECT AVG(cnt) FROM cnts)
否则查询会变得更加复杂,主查询也需要作为 WHERE
子句中的子查询:
SELECT country.country_name, city.city_name, COUNT(customer.city_id) AS cnt
FROM country
JOIN city on country.id = city.country_id
JOIN customer on city.id = customer.city_id
GROUP BY city_name,country.country_name
HAVING COUNT(customer.city_id) > (SELECT AVG(cnt) FROM (
SELECT country.country_name, city.city_name, COUNT(customer.city_id) AS cnt
FROM country
JOIN city on country.id = city.country_id
JOIN customer on city.id = customer.city_id
GROUP BY city_name,country.country_name
) cnts2)
在这两种情况下,样本数据的输出都是:
country_name city_name cnt
Brazil Rio 3
US Dallas 2
您可以使用 window 函数:
SELECT cc.*
FROM (SELECT co.country_name, ci.city_name, COUNT(*) AS cnt,
AVG(COUNT(*)) OVER () as avg_count
FROM country co JOIn
city ci
ON co.id = ci.country_id JOIN
customer cu
ON ci.id = cu.city_id
GROUP BY ci.city_name, co.country_name
) cc
WHERE cnt > avg_count;
我有 3 个不同的 table,国家、城市和客户。表格如下:
国家table:
id country_name
1 UK
2 US
3 Brazil
:
n Canada
城市table
id city_name postal_code country_id
1 London 30090 1
2 Dallas 20909 2
3 Rio 29090 3
4 Atlanta 30318 2
:
n Vancouver 32230 n
顾客table
id customer_name city_id
1 John 1
2 Pete 3
3 Dave 2
4 May 2
5 Chuck 4
6 Sam 3
7 Henry 3
***country.id 是引用 city.country_id,city.id 是引用 customer.city_id
我想写一个查询,可以提取国家名称、城市名称和相关城市的客户数量。但是在一个条件下,查询将 return 所有城市的客户数量超过所有城市的平均客户数量
它看起来像下面这样,这是正确的输出
UK London 2
Brazil Rio 3
但我一直得到这个输出,这是不正确的
UK London 2
US Dallas 2
US Atlanta 1
Brazil Rio 3
我写了一个 SQL 查询,但它没有给我想要的结果
SELECT country.country_name, city.city_name, COUNT(customer.city_id) from country
JOIN city on country.id = city.country_id
JOIN customer on city.id = customer.city_id
Group by city_name,country.country_name;
我想知道如何执行此操作并修复我的代码?
您需要将查询嵌套到子查询中,以便您可以取计数的平均值并将当前计数与其进行比较。如果您使用的是支持 CTE 的 SQL,您可以使用一个
WITH cnts AS (
SELECT country.country_name, city.city_name, COUNT(customer.city_id) AS cnt
FROM country
JOIN city on country.id = city.country_id
JOIN customer on city.id = customer.city_id
GROUP BY city_name,country.country_name
)
SELECT *
FROM cnts
WHERE cnt > (SELECT AVG(cnt) FROM cnts)
否则查询会变得更加复杂,主查询也需要作为 WHERE
子句中的子查询:
SELECT country.country_name, city.city_name, COUNT(customer.city_id) AS cnt
FROM country
JOIN city on country.id = city.country_id
JOIN customer on city.id = customer.city_id
GROUP BY city_name,country.country_name
HAVING COUNT(customer.city_id) > (SELECT AVG(cnt) FROM (
SELECT country.country_name, city.city_name, COUNT(customer.city_id) AS cnt
FROM country
JOIN city on country.id = city.country_id
JOIN customer on city.id = customer.city_id
GROUP BY city_name,country.country_name
) cnts2)
在这两种情况下,样本数据的输出都是:
country_name city_name cnt
Brazil Rio 3
US Dallas 2
您可以使用 window 函数:
SELECT cc.*
FROM (SELECT co.country_name, ci.city_name, COUNT(*) AS cnt,
AVG(COUNT(*)) OVER () as avg_count
FROM country co JOIn
city ci
ON co.id = ci.country_id JOIN
customer cu
ON ci.id = cu.city_id
GROUP BY ci.city_name, co.country_name
) cc
WHERE cnt > avg_count;