【问题标题】:How do I query a column where a specific number does not exist in any of the rows of that column如何查询该列的任何行中都不存在特定数字的列
【发布时间】:2020-12-05 20:44:41
【问题描述】:

我有ID | Name | Salary,类型分别为Integer | String | Integer

我需要查询 Salary 列的所有行的 avg,然后再次查询 Salary 列的所有行的 avg,但是如果其中任何一行包含 0,则从这些数字中删除 0,然后计算平均值。

所以如果 Salary 返回 1420, 2006, 500,下一个查询应该返回 142, 26, 5。然后我计算后续不包含 0 的数字的平均值。

我尝试用谷歌搜索我的具体问题,但没有找到任何接近解决方案的东西。我不是在寻找答案,而是朝着正确的方向努力。

我的想法

  • 也许我需要将integer 数据类型转换为varchar 或字符串,然后从那里删除“0”数字,然后再转换回来?
  • 也许我需要从第一个表结果创建一个临时表,然后插入它们,只是没有 0?

有什么想法吗?希望我很清楚。谢谢!

示例表数据:

ID | Name     | Salary
---+----------+-------
1  | Kathleen | 1420
2  | Bobby    |  690
3  | Cat      |  500

现在我需要查询上表,但工资行中的 0 已删除

ID | Name     | Salary
---+----------+-------
1  | Kathleen | 142
2  | Bobby    |  69
3  | Cat      |   5

【问题讨论】:

  • 为什么要删除零?为什么你会从 2006 年到 26 年?
  • 我的问题需要我这样做。
  • 让帮助您变得简单且可能 - 向我们展示一些示例表数据和预期结果(格式文本,无图像。)minimal reproducible example
  • 101呢,应该是11吧?
  • 我会选择“思想 1”。

标签: sql string average aggregate-functions


【解决方案1】:

您想从您的数字中删除所有0s,然后对结果进行数值平均。正如您所预见的,这需要混合字符串和数字操作。

实际语法因数据库而异。在 MySQL、SQL Server 和 Oracle 中,你应该可以做到:

select avg(replace(salary, '0', '') + 0) as myavg
from mytable

这涉及两个隐式转换步骤:replace() 强制字符串上下文,+ 0 将结果转换回数字。在 SQL Server 中,您将获得一个整数结果 - 如果您想要一个小数平均值,您可能需要添加一个小数 - 所以 + 0.0 而不是 + 0

在 Postgres 中,隐式转换不容易发生,您可以使用显式转换:

select avg(replace(salary::text, '0', '')::int) as myavg
from mytable

这将返回一个十进制值。

【讨论】:

    【解决方案2】:

    你只是想要条件聚合吗?

    select avg(salary), avg(case when salary <> 0 then salary end)
    from t;
    

    还是要除法?

    select id, name, floor(salary / 10)
    from t;
    

    这会产生您指定的结果,但与“平均”无关。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-17
      • 1970-01-01
      • 1970-01-01
      • 2013-12-14
      • 1970-01-01
      • 2014-09-18
      • 2017-11-25
      • 1970-01-01
      相关资源
      最近更新 更多