这是我一直在研究一段时间没有结果的SQL问题。
架构是
CREATE TABLE states (
statecode text primary key,
population_2010 integer,
population_2000 integer,
population_1950 integer,
population_1900 integer,
landarea real,
name text,
admitted_to_union text
);
CREATE TABLE counties(
name text,
statecode text references states(statecode),
population_1950 integer,
population_2010 integer
);
CREATE TABLE senators(
statecode text references states(statecode),
name text primary key,
affiliation text,
took_office integer,
born integer);
CREATE TABLE committees(
id text primary key,
parent_committee text references committees(id),
name text,
chairman text references senators(name),
ranking_member text references senators(name)
);
问题是: 返回有多少州的数量超过平均县数
我知道如何计算平均值:
select avg(state_count)
from
(select count(*) as state_count
from counties C
group by C.statecode)
但我想知道我是否可以重用子查询。
像这样(以下一个不起作用):select count(*) as state_count
from counties C
group by C.statecode
having count(*) > avg(state_count)
此查询仍然不计算行数,是否有优雅的方式?
修改 刚刚找到了一个示例答案
SELECT COUNT(*)
FROM (SELECT statecode, COUNT(*) AS counts
FROM counties
GROUP BY statecode) s
WHERE s.counts > (SELECT AVG(t.counts)
FROM (SELECT COUNT(*) AS counts
FROM counties
GROUP BY statecode) t);
但如果有更好的方法,我仍然很好奇吗?
答案 0 :(得分:2)
您提供的样本答案的不经济部分是
SELECT COUNT(*) AS counts
FROM counties
GROUP BY statecode
此部分出现两次,一次用于计算平均值,一次用于查找大于平均值的计数。所以这是我尝试使用CTE,它将上述代码重用于以下两个目的:
WITH c AS
(
SELECT COUNT(*) AS counts
FROM counties
GROUP BY statecode
)
SELECT COUNT(*) FROM c WHERE counts > (SELECT Avg(CAST(counts AS decimal))
FROM c)
答案 1 :(得分:0)
我认为您可以简化以下查询。我使用一个简单的(不相关的)子查询来计算每个州的平均县数,方法是将县总数除以州的总数。
SELECT COUNT(*) AS states_above_average_count
FROM
(
SELECT statecode
FROM counties
GROUP BY statecode
HAVING COUNT(*) > (SELECT COUNT(*) FROM counties) / (SELECT COUNT(*) FROM states)
) t
答案 2 :(得分:0)
您可以使用CTE
WITH States AS (
SELECT COUNT(*) as state_count
FROM counties t
GROUP BY t.statecode)
select count(*) from( SELECT count(*) as state_count from
counties t
GROUP BY t.statecode
having count(*)> (select avg(x.state_count) from States x)) as g