Sql 如何查找列中所有值之和达到指定值的行?

Sql 如何查找列中所有值之和达到指定值的行?,sql,sql-server,Sql,Sql Server,具有以下架构的表中的给定数据: CREATE TABLE purchases (timestamp DATETIME, quantity INT) 我想找到时间点,即quantity列中的值之和超过某个阈值的行的时间戳 这是在MS SQL Server中,如果可能的话,我希望避免使用游标 SELECT timestamp, SUM(quantity) FROM purchases GROUP BY timestamp HAVING SUM(quantity) > someValue 或

具有以下架构的表中的给定数据:

CREATE TABLE purchases (timestamp DATETIME, quantity INT)
我想找到时间点,即quantity列中的值之和超过某个阈值的行的时间戳

这是在MS SQL Server中,如果可能的话,我希望避免使用游标

SELECT timestamp, SUM(quantity)
FROM purchases
GROUP BY timestamp
HAVING SUM(quantity) > someValue
或者如果它是一个连续的总和

SELECT a1.timestamp
FROM purchases a1, purchases a2 
WHERE a1.quantity >= a2.quantity or (a1.quantity=a2.quantity and a1.timestamp = a2.timestamp) 
GROUP BY a1.timestamp, a1.quantity
having SUM(a2.quantity) >= someValue
ORDER BY a1.timestamp ASC
LIMIT 1
或者如果它是一个连续的总和

SELECT a1.timestamp
FROM purchases a1, purchases a2 
WHERE a1.quantity >= a2.quantity or (a1.quantity=a2.quantity and a1.timestamp = a2.timestamp) 
GROUP BY a1.timestamp, a1.quantity
having SUM(a2.quantity) >= someValue
ORDER BY a1.timestamp ASC
LIMIT 1

如果先前值的总和大于阈值,则可以获得最小的时间戳:

select min(timestamp)
from purchases p
where (
  select sum(x.quantity)
  from purchases x
  where x.timestamp < p.timestamp
) > @threshold

但是,这不是一个非常有效的查询,因此最好还是使用游标。

如果前面的值之和大于阈值,则可以获得最小的时间戳:

select min(timestamp)
from purchases p
where (
  select sum(x.quantity)
  from purchases x
  where x.timestamp < p.timestamp
) > @threshold

但是,这不是一个非常有效的查询,因此最好还是使用游标。

在SQL Server 2005+中,您可以尝试以下方法:

;WITH numbered AS (
  SELECT
    timestamp,
    quantity,
    rownum = ROW_NUMBER() OVER (ORDER BY timestamp)
  FROM purchases
),
recursive AS (
  SELECT
    timestamp,
    quantity,
    rownum,
    runningsum = quantity,
    passed = CASE WHEN n.quantity < @threshold THEN 0 ELSE 1 END
  FROM numbered
  UNION ALL
  SELECT
    n.timestamp,
    n.quantity,
    n.rownum,
    runningsum = n.quantity + r.runningsum,
    passed = CASE WHEN n.quantity + r.runningsum < @threshold THEN 0 ELSE 1 END
  FROM numbered n
    INNER JOIN recursive r ON n.rownum = r.rownum + 1
)
SELECT MIN(timestamp)
FROM recursive
WHERE passed = 1

基本上,与的解决方案相同,只使用CTE来避免三角连接的需要。

在SQL Server 2005+中,您可以尝试以下方法:

;WITH numbered AS (
  SELECT
    timestamp,
    quantity,
    rownum = ROW_NUMBER() OVER (ORDER BY timestamp)
  FROM purchases
),
recursive AS (
  SELECT
    timestamp,
    quantity,
    rownum,
    runningsum = quantity,
    passed = CASE WHEN n.quantity < @threshold THEN 0 ELSE 1 END
  FROM numbered
  UNION ALL
  SELECT
    n.timestamp,
    n.quantity,
    n.rownum,
    runningsum = n.quantity + r.runningsum,
    passed = CASE WHEN n.quantity + r.runningsum < @threshold THEN 0 ELSE 1 END
  FROM numbered n
    INNER JOIN recursive r ON n.rownum = r.rownum + 1
)
SELECT MIN(timestamp)
FROM recursive
WHERE passed = 1

基本上,与的解决方案相同,只使用CTE来避免三角形连接的需要。

您能给出示例数据吗?这是一个给定时间戳上的总和,还是一个正在运行的总和?是一个堆,还是在时间戳上有一个索引?您能给出示例数据吗?这是给定时间戳上的总和,还是正在运行的总和?这是一个堆,还是时间戳上有索引?假设OP有时间戳上的索引,并且它是升序,那么是MAX而不是MIN。或者只是运算符from的一个更改。对我来说没问题。由于OP不是完全特定的,因此存在边界定义问题:集合的最后一行。但他们可以弄明白。假设OP在时间戳上有一个索引,它是递增的,那么MAX不是MIN。或者只是在操作符中做了一个更改。我同意。由于OP不是完全特定的,因此存在边界定义问题:集合的最后一行。但他们可以找到答案。