【问题标题】:Why percentage is not working properly in SQLite3?为什么百分比在 SQLite3 中无法正常工作?
【发布时间】:2014-10-15 02:19:51
【问题描述】:

对于以下问题,我有以下代码,但是百分比恰好为零:

SELECT p.state, (p.popestimate2011/sum(p.popestimate2011)) * 100
FROM pop_estimate_state_age_sex_race_origin p
WHERE p.age >= 21
GROUP BY p.state;

还有这里的表架构:

sqlite> .schema pop_estimate_state_age_sex_race_origin
CREATE TABLE pop_estimate_state_age_sex_race_origin (
   sumlev NUMBER, 
   region NUMBER, 
   division NUMBER, 
   state NUMBER, 
   sex NUMBER, 
   origin NUMBER, 
   race NUMBER, 
   age NUMBER, 
   census2010pop NUMBER, 
   estimatesbase2010 NUMBER, 
   popestimate2010 NUMBER, 
   popestimate2011 NUMBER, 
   PRIMARY KEY(state, age, sex, race, origin), 
   FOREIGN KEY(sumlev) REFERENCES SUMLEV(sumlev_cd), 
   FOREIGN KEY(region) REFERENCES REGION(region_cd), 
   FOREIGN KEY(division) REFERENCES DIVISION(division_cd), 
   FOREIGN KEY(sex) REFERENCES SEX(sex_cd), 
   FOREIGN KEY(race) REFERENCES RACE(race_cd), 
   FOREIGN KEY(origin) REFERENCES ORIGIN(origin_cd));

所以当我运行查询时,它只显示百分比为 0:

stat  p.popestimate
----  -------------
1     0            
2     0            
4     0            
5     0            
6     0            
8     0            
9     0            
10    0            
11    0            
12    0            
13    0            
15    0            
16    0            
17    0            
18    0            
19    0            
20    0            
21    0            
22    0            
23    0    

我试图使用嵌套查询来编写它,但也没有得到任何地方:

    SELECT p.state, 100.0 * sum(p.popestimate2011) / total_pop AS percentage
FROM pop_estimate_state_age_sex_race_origin p
JOIN (SELECT state, sum(p2.popestimate2011) AS total_pop
      FROM pop_estimate_state_age_sex_race_origin p2) s ON (s.state = p.state)
WHERE age >= 21
GROUP BY p.state, total_pop
ORDER BY p.state;

我目前遇到的问题是它只显示一行作为结果,并且只显示最后一个状态号(状态 ID=56)的结果:

56    0.131294163192301

【问题讨论】:

  • 您能否给出一个提示,而不是仅仅投反对票并关闭问题?你也可以像 stackexchange 的道德规范中提到的那样“做个好人”吗?不是每个人都知道一切!
  • 您的任务需要嵌套查询。
  • @PM77-1 你能看看我更新问题的结尾吗?嵌套查询不起作用。你能给出任何提示有什么问题吗?
  • 根据新的编辑撤回反对票。样本数据(和预期结果)将是相关的。在子查询中添加 GROUP BY 子句。
  • 如果您明确使用 SQLite,为什么还要用 postgresql 标记它?

标签: sql database postgresql sqlite


【解决方案1】:

这是一种不需要内部查询的方法(未经测试)。它对表格进行一次遍历,按州聚合,并使用CASE 计算 20 岁以上人口的分子和州总人口的分母。

 SELECT 
    state,
    (SUM(CASE WHEN age >= 21 THEN popestimate2011 ELSE 0) / SUM(popestimate2011)) * 100
 FROM pop_estimate_state_age_sex_race_origin 
 GROUP BY state

【讨论】:

  • 您认为 OP 想要州内成年人与所有人的百分比吗?
  • 是的,据我了解,我们被要求计算每个州的成年人百分比,而不是该州对总成年人口的贡献百分比。
【解决方案2】:

我不知道为什么你的 SQL 语句正在执行。您将非聚合列值 popestimate2011 包含在 GROUP BY 选择中,这应该会产生错误。

仔细阅读 SQLite 文档表明它确实实际上支持结果表达式列表中非聚合列的随机值选择(MySQL 也提供了这一功能)。这说明:

  1. 为什么您的 SELECT 语句能够执行(为非聚合的 popestimate2011 引用选择了一个随机值)。
  2. 为什么您看到的结果为 0:选择的随机值可能是第一个出现的行,如果这些行按顺序添加到数据库中,那么该行的年龄值可能为 0。因为除法中的分子将那么为0,结果也是0。

至于计算的内容,从表定义中不清楚您的基表中的数据是否已经聚合,如果是,age 列代表什么(一个平均值?该行的分组因子?)

最后,SQLite 没有NUMBER 数据类型。这些列将获得NUMERIC 的默认亲和力,这可能是您想要的,但也可能不是。

【讨论】:

  • 我也想知道 OP 脚本的合法性。我以为只有MySQL 这么宽容。
  • 好吧,SQLite3 有 NUMBER 数据类型,到目前为止,我运行其余的查询没有问题。
  • @larry AGE 是单岁(0、1、2、...84、85 岁以上)。
  • 我只会重复 SQLite 确实没有NUMBER 数据类型(或者,实际上是任何数据类型,所以说它没有更准确有一个NUMBER 存储类)。文档在这里:sqlite.org/datatype3.html.
  • @PM77-1:搜索 SQLite 文档,我能够确定它确实为GROUP BY 查询中的非聚合列实现了 MySQL 随机值逻辑(这让我感到惊讶) .
【解决方案3】:

您需要这些方面的东西(未经测试):

SELECT state,  SUM(popestimate2011) / 
               (SELECT SUM(popestimate2011) 
                FROM pop_estimate_state_age_sex_race_origin 
                WHERE age > 21)))      
               * 100 as percentage
FROM pop_estimate_state_age_sex_race_origi
WHERE age >= 21
GROUP by state      
;

【讨论】:

  • 我认为该内部查询上的WHERE 子句需要是WHERE state = OT.state(其中OT 是外部查询中表的别名),并且必须省略年龄。
  • @LarryLustig :我的内部查询正在计算总和(常数)。 应该是相关查询。就WHERE 而言,我的理解是我们正在将各州的成年人口与成年人口进行比较。
  • 我对问题陈述的理解是,您的目的是计算超过 21 岁的每个州人口的百分比,而不是计算该州的贡献百分比占成年人口。我看错了吗?
  • @LarryLustig - 老实说,我不知道。可能是我误解了 OP 想要什么。
  • 如果我错了,顺便说一句,我收回我之前的评论——您的查询会按照您的描述计算数字。
【解决方案4】:

SQLite 中不存在 NUMBER 类型。 SQLite 解释为 INTEGER 和 整数除法中会丢失小数

(p.popestimate2011 / sum (p.popestimate2011))

始终为 0。

改变列popestimate2011 REAL的类型 或使用 CAST (...)

(CAST (p.popestimate2011 AS REAL) / SUM (p.popestimate2011))

【讨论】:

  • 虽然 SQLite 确实没有 NUMBER 类型,但 not 确实将 NUMBER 类型声明视为 INT。它们被视为 NUMERIC,它 not 转换小数。这不是这里发生的问题。
猜你喜欢
  • 2016-10-19
  • 2011-07-24
  • 2017-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多