【问题标题】:Return row when SUM(column) = value, on SQL Server在 SQL Server 上,当 SUM(column) = value 时返回行
【发布时间】:2017-03-09 20:41:28
【问题描述】:

我的桌子:

id int(11) AUTO_INCREMENT
date date
number int(3)

+----+------------+--------+
| id | date       | number |
+----+------------+--------+    
| 1  | 2010-01-02 |   0    |
| 2  | 2010-01-03 |   3    |
| 3  | 2010-01-04 |   0    |
| 4  | 2010-01-05 |   2    |
| 5  | 2010-01-06 |   1    |
| 6  | 2010-01-07 |   3    |
+----+------------+--------+

我想返回数字之和为6且日期>'2010-01-04'的日期

我想返回添加字段号等于 6 的日期(在特定日期之后,在本例中为 2010-01-04)。示例:我的查询应该返回 2010-01-07 因为 2 在 2010-01-05 1 在 2010-01-06 3 在 2010-01-07

到目前为止,我一直在 MySQL 服务器上使用此查询:

select date 
    from 
      (select date, @n:=@n+total total 
          from 
            (select date, sum(number) total 
                from MyTable 
              where date > '2010-01-04' 
              group by date 
              order by date 
            ) t 
           cross join 
            (select @n:=0) n 
      ) tt 
   where total = 6

现在,我们只有一台服务器,在 SQL Server 上,我在 SQL Server 上使用此查询时遇到了一些问题。

【问题讨论】:

  • 你不能在 sql server 上使用这个查询。

标签: sql sql-server sum


【解决方案1】:

在这种情况下,您可以使用:

with calc as 
(
    select top 100 percent
                t1.id, t1.dt, SUM(t2.num) acm
    from        MyTable t1
    inner join  MyTable t2 on t1.id >= t2.id
    group by    t1.id, t1.dt
    order by    t1.id
)
select top 1 id, dt as Date, Acm
from   calc
where  Acm >= 6;

结果:

|id|Date               |Acm|
|-:|:------------------|--:|
| 5|06/01/2010 00:00:00|  6|

另一种方法:

with calc2 as
(
    select id, dt, sum(num) over (order by dt) acm
    from @csum
)
select top 1 id, dt as Date, Acm
from   calc2
where  Acm >= 6;

检查一下 dbfiddle here

更新

如果每次累积和达到6时都需要一个重置点,那就有点复杂了。

with calc2 as
(
    select id, dt, num,
           sum(num) over (order by dt) acm, 
           sum(num) over (order by dt) / 6 reset
    from @csum
)
select id, dt as Date
from   @csum
where  id in (select min(id) from calc2 t2 where reset > 0 group by reset);

每次累积总和达到 6 时,第一个 CTE 设置一个重置点。(请记住,它在 SUM() = 6 时重置)

第二个查询返回每个“重置”分区的第一行。

(select min(id) from calc2 t2 where reset > 0 group by reset)

试试 dbfiddle here

【讨论】:

  • 谢谢!!这行得通。我在查询中添加了字段日期:with calc as ( select top 100 percent t1.id, t1.date, SUM(t2.num) acm from mytable t1 inner join mytable t2 on t1.id >= t2.id其中 t2.date > '2017-02-24' group by t1.id, t1.date order by t1.id ) 选择 top 1 id, date as Date, Acm from calc where Acm >= 4 AND date > '2017- 02-24';您是否有想法返回每个 acm = 6 的所有日期? with start date 是之前返回的日期
  • 你的意思是:每次达到6,重置为0?
  • 我已经用我的数据测试了你的代码更新。返回的第一个日期是错误的,但第一个日期之后的所有日期都是正确的。
  • 通过使用 calc2 中的查询,您可以看到发生了什么。 @皮埃尔001
【解决方案2】:

你为什么不试试这个:

WITH
-- input, don't use in real query
input(id,the_date,the_number) AS (
          SELECT 1,DATE '2010-01-02',0
UNION ALL SELECT 2,DATE '2010-01-03',3
UNION ALL SELECT 3,DATE '2010-01-04',0
UNION ALL SELECT 4,DATE '2010-01-05',2
UNION ALL SELECT 5,DATE '2010-01-06',1
UNION ALL SELECT 6,DATE '2010-01-07',3
)
-- end of input, start "real" WITH clause here
,
run_sum AS (
SELECT
  *
, SUM(the_number) OVER(ORDER BY id) AS the_sum
FROM input
WHERE the_date > '2010-01-04'
)
-- the above returns:
-- SELECT * FROM run_sum;
-- id|the_date  |the_number|the_sum
--  4|2010-01-05|         2|      2
--  5|2010-01-06|         1|      3
--  6|2010-01-07|         3|      6
SELECT
  the_date
FROM run_sum
WHERE the_sum = 6
;

【讨论】:

    【解决方案3】:

    如果你有 MSSQL 2012,你可以试试这个:

    SELECT DATE 
        FROM 
          (SELECT DATE, SUM(TOTAL) OVER (ORDER BY DATE ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS TOTAL
              FROM 
                (SELECT DATE, SUM(NUMBER) TOTAL 
                    FROM MYTABLE
                  WHERE DATE > CONVERT(DATE, '2010-01-04',121) 
                  GROUP BY DATE               
                ) T         
          ) TT 
       WHERE TOTAL = 6
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-16
      相关资源
      最近更新 更多