[英]how to write the following SQL query involving sub queries
我有下表名為population
:
╔════════════╦════════════╦════════════════╗
║ india ║ hyderabad ║ 50100 ║
║ india ║ delhi ║ 75000 ║
║ USA ║ NewYork ║ 25000 ║
║ USA ║ california ║ 30000 ║
║ india ║ delhi ║ 5000 ║
║ USA ║ NewYork ║ 75000 ║
╚════════════╩════════════╩════════════════╝
我需要編寫一個 SQL 查詢來獲取以下格式的數據:
╔════════╦═════════╦══════════╗
║ india ║ delhi ║ 80000 ║
║ USA ║ NewYork ║ 100000 ║
╚════════╩═════════╩══════════╝
國家名稱和人口最多的城市,城市的多個條目匯總在一起。
您可以使用:
SELECT *
FROM (
SELECT country,city, SUM(pop) AS total
FROM population
GROUP BY country,city) AS sub
WHERE (country, total) IN (
SELECT country, MAX(total)
FROM (SELECT country,city, SUM(pop) AS total
FROM population
GROUP BY country,city
) as s
GROUP BY country
);
如果同一國家/地區的兩個城市的總人口最多,那么您將獲得該國家/地區的兩個城市。
輸出:
╔══════════╦═════════╦════════╗
║ country ║ city ║ total ║
╠══════════╬═════════╬════════╣
║ india ║ delhi ║ 80000 ║
║ USA ║ NewYork ║ 100000 ║
╚══════════╩═════════╩════════╝
您可以組合使用 GROUP_CONCAT 和 FIND_IN_SET。 此查詢將返回每個國家/地區的逗號分隔城市列表,按人口 DESC 排序:
SELECT country, GROUP_CONCAT(city ORDER BY pop DESC) AS cities
FROM population
GROUP BY country
它將返回如下內容:
| country | cities |
|---------|--------------------------|
| india | delhi,hyderabad,delhi |
| USA | NewYok,california,NewYok |
然后我們可以使用返回城市列表中城市位置的 FIND_IN_SET 將此子查詢連接回人口表:
SELECT
p.country,
p.city,
SUM(p.pop)
FROM
population p INNER JOIN (
SELECT country, GROUP_CONCAT(city ORDER BY pop DESC) AS cities
FROM population
GROUP BY country
) m ON p.country=m.country
AND FIND_IN_SET(p.city, m.cities)=1
GROUP BY
p.country,
p.city
連接只會在每個國家/ FIND_IN_SET(p.city, m.cities)=1
人口最多的城市上成功: FIND_IN_SET(p.city, m.cities)=1
。
這僅在有一個城市的最大污染時才有效,如果有更多,則只會返回一個。 這也不是標准 SQL,只能在 MySQL 或類似的東西上工作,其他 DBMS 具有窗口函數,可以使相同的查詢更容易編寫。
以下答案不正確,因為它使用了違反 ANSI 標准的特定於 Mysql 的功能。 結果是不確定的,因為它沒有定義按國家聚合時將返回哪個城市名稱。 大多數情況下,它是將使用的第一個條目,這就是為什么在內部查詢中進行排序在大多數情況下都可以工作的原因。 但要注意:根據定義,不能保證使用第一個城市,因此在某些情況下可能會輸出錯誤的結果。 此答案未涵蓋的另一種情況是,當有兩個城市的人口與一個國家的最大值相同時。 該解決方案將僅輸出每個國家/地區的一個城市。
我會用一個內部子查詢來解決它,該子查詢將所有城市分組,而外部過濾器僅獲得按國家/地區划分的最大城市。
SELECT
country, city, MAX(population_total) AS population_total
FROM
(
SELECT country, city, SUM(population) AS population_total
FROM tableName
GROUP BY country, city
ORDER BY population_total DESC
) AS t1
GROUP BY
country
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.