【问题标题】:SQL query - find row which exceeds cumulative proportionSQL查询-查找超过累积比例的行
【发布时间】:2011-12-16 09:46:01
【问题描述】:

假设我有一个如下所示的数据表:

ItemNo    |    ItemCount   |    Proportion
------------------------------------------
1              3                0.15 
2              2                0.10
3              3                0.15
4              0                0.00
5              2                0.10
6              1                0.05
7              5                0.25
8              4                0.20

也就是说,总共有20个项目,每个ItemNo的累计比例总和为100%。表格行的顺序在这里很重要。

是否可以不使用循环或游标执行 SQL 查询以返回超过累积比例的第一个 ItemNo

换句话说,如果我要检查的“比例”是 35%,那么超过该比例的第一行是 ItemNo 3,因为 0.15 + 0.10 + 0.15 = 0.40

同样,如果我想找到超过 75% 的第一行,那就是 ItemNo 7,因为直到该行小于 0.75 为止,所有 Proportion 的总和。

【问题讨论】:

    标签: sql sql-server cumulative-frequency


    【解决方案1】:
    select top 1
      t1.ItemNo
    from
      MyTable t1
    where
      ((select sum(t2.Proportion) from MyTable t2 where t2.ItemNo <= t1.ItemNo) >= 0.35)
    order by
      t1.ItemNo
    

    【讨论】:

      【解决方案2】:

      一个经典的窗口函数:

      SELECT * 
      FROM   (
          SELECT ItemNo
                ,ItemCount
                ,sum(Proportion) OVER (ORDER BY ItemNo) AS running_sum
          FROM   tbl) y
      WHERE  running_sum > 0.35
      LIMIT  1;
      

      PostgreSQL 等中工作。

      或者,用 tSQL 表示法(您似乎使用):
      选择前 1 个 *
      来自 (
      选择项目编号
      ,ItemCount
      ,sum(比例) OVER (ORDER BY ItemNo) AS running_sum
      来自 tbl) y
      WHERE running_sum > 0.35;

      在 tSQL 中不起作用,如下所述。

      【讨论】:

      • 在 Sql Server 中使用的语法有细微的差别吗?当使用你的第二个例子时,我得到Incorrect syntax near 'order'.
      • 我可能弄错了,但我认为 OVER 子句不能用于在 SQL Server 中生成运行总计,只能用于分区的排名或总和。请参阅stackoverflow.com/questions/860966/… 这就是我选择子查询的原因。
      • @njreed.myopenid.com:啊,看起来你是对的,不适用于 tSQL。很好的链接。我划掉了 tSQL 版本。请记住在您的嵌套问题中披露您的 RDBMS。 :)
      • @Erwin 感谢您的澄清。不指定 RDBMS 是经过深思熟虑的选择,以便在无需依赖供应商特定功能的情况下获得通用 SQL 解决方案。
      猜你喜欢
      • 1970-01-01
      • 2020-07-24
      • 1970-01-01
      • 2011-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多