【问题标题】:Rows in table with specific sum of a column表中具有特定列总和的行
【发布时间】:2014-07-02 11:52:54
【问题描述】:

我有一个表格,其中包含一些看起来像这样的付款:

id  |  from  |  to  |  amount
--------------------------
1   |   125  | 135  |  2.4
2   |   123  | 134  |  1.7
3   |   124  | 138  |  4.8
4   |   118  | 119  |  3.9
5   |   56   | 254  |  23.5
... 

我需要知道是否有一种方法可以进行 SQL 查询,它会告诉我是否有一系列连续的行,其数量总计为某个值。例如,如果我想要值 6.5,它将返回第 2 到第 3 行。如果我想要 12.8,它将返回第 1 到第 4 行,依此类推。

我完全被卡住了,希望能得到一些帮助。

【问题讨论】:

  • 你需要有一个循环来检查所需输出的总和,然后输出行
  • SQL Server 的哪个版本?
  • 只是一般性的一点——对于一个足够大的可能是一个运行时间极长的查询的表,至少要确保删除任何大于您正在搜索的值的“数量”。
  • 问题是,也可能有负值:-/

标签: sql sql-server tsql sql-server-2012


【解决方案1】:

我会这样处理。首先,计算累积和。那么,连续行具有特定和的条件相当于说两个累积和之间的差等于该值。

with p as (
      select p.*, sum(amount) over (order by id) as cumamount
      from payments p
     )
select 
from p p1 join
     p p2
     on p1.id <= p2.id and
       ( p2.cumamount - p1.cumamount ) = 6.5;

注意:如果amount 存储为浮点数,这可能不起作用,因为误差非常小。如果amount 是一个整数,那很好,但显然不是。定点表示应该没问题。

【讨论】:

  • 我认为您需要在开始时添加一个 0 行,以便当集合从第一行开始时,此方法才能工作? (虽然我手头没有 2012 年,所以我可能误解了)
  • @podiluska 。 . .不可以。但如果该集合仅包含一行,则 &lt; 需要是 &lt;=。我只是做了那个改变,尽管这个问题似乎强调了复数形式的行。
  • 对于那些以前从未听说过的人:en.wikipedia.org/wiki/Prefix_sum
【解决方案2】:
;with numbers as (select number from master..spt_values where type='p' and number between 1 and (Select MAX(id) from yourtable)),
ranges as ( select n1.number as start, n2.number as finish from numbers n1 cross join numbers n2 where n1.number<=n2.number)
    select yourtable.* from yourtable
        inner join
        (
            select start, finish
            from ranges
                inner join yourtable on id between start and finish
            group by start, finish
            having SUM(amount)=12.8 
        ) results
    on yourtable.id between start and finish

【讨论】:

猜你喜欢
  • 2016-04-28
  • 1970-01-01
  • 1970-01-01
  • 2012-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-19
  • 1970-01-01
相关资源
最近更新 更多