从列中获取平均值,然后过滤掉数量小于平均值的所有行,然后计算行数

时间:2016-10-14 23:31:46

标签: sql database sqlite

这是我一直在研究一段时间没有结果的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);

但如果有更好的方法,我仍然很好奇吗?

3 个答案:

答案 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