鑑於數據與下面的模式:如何查找列中所有值的總和達到指定值的行?在表
CREATE TABLE purchases (timestamp DATETIME, quantity INT)
我想找到的時間點(即該行的時間戳),其中在數量列中的值的總和通過一定的閾值值。
這是在MS SQL Server中,理想情況下我想避免使用遊標,如果可能的話。
鑑於數據與下面的模式:如何查找列中所有值的總和達到指定值的行?在表
CREATE TABLE purchases (timestamp DATETIME, quantity INT)
我想找到的時間點(即該行的時間戳),其中在數量列中的值的總和通過一定的閾值值。
這是在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 min(timestamp)
from purchases p
where (
select sum(x.quantity)
from purchases x
where x.timestamp < p.timestamp
) > @threshold
然而,這不是一個非常有效的查詢,所以最好使用遊標。
界限錯誤,應該是時間戳<=時間戳 – RichardTheKiwi 2011-03-07 06:45:33
假設OP在時間戳上有一個索引,並且它是遞增的,那麼MAX()不是MIN()。 – PerformanceDBA 2011-03-07 07:40:16
或者只是從'<' to '>'中修改運算符。 – Guffa 2011-03-07 12:02:22
在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的解決方案,只是利用熱膨脹係數,以避免需要三角形的加入。
@理查德:謝謝,修正。 – 2011-03-07 09:16:40
你可以提供樣本數據嗎?這是這個SUM在給定的時間戳上,還是正在運行的SUM? – gbn 2011-03-07 05:27:13
它是一個堆,還是你有一個索引(時間戳)? – PerformanceDBA 2011-03-07 07:38:23