在具有以下模式的表中给出数据:
CREATE TABLE purchases (timestamp DATETIME, quantity INT)
我想找到时间点(即行的时间戳),其中数量列中的值总和超过了某个阈值。
这是在MS SQL Server中,理想情况下我想尽可能避免使用游标。
答案 0 :(得分:2)
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
答案 1 :(得分:1)
您可以获得前一个值之和大于阈值的最小时间戳:
select min(timestamp)
from purchases p
where (
select sum(x.quantity)
from purchases x
where x.timestamp < p.timestamp
) > @threshold
但是,这不是一个非常有效的查询,所以最好使用游标。
答案 2 :(得分:0)
在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
基本上,与@Guffa的解决方案相同,只使用CTE来避免三角形连接的需要。