2011-03-07 51 views
0

鑑於數據與下面的模式:如何查找列中所有值的總和達到指定值的行?在表

CREATE TABLE purchases (timestamp DATETIME, quantity INT) 

我想找到的時間點(即該行的時間戳),其中在數量列中的值的總和通過一定的閾值值。

這是在MS SQL Server中,理想情況下我想避免使用遊標,如果可能的話。

+0

你可以提供樣本數據嗎?這是這個SUM在給定的時間戳上,還是正在運行的SUM? – gbn 2011-03-07 05:27:13

+0

它是一個堆,還是你有一個索引(時間戳)? – PerformanceDBA 2011-03-07 07:38:23

回答

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

你可以得到最小的時間戳,其中先前值的總和大於閾值:

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

然而,這不是一個非常有效的查詢,所以最好使用遊標。

+0

界限錯誤,應該是時間戳<=時間戳 – RichardTheKiwi 2011-03-07 06:45:33

+0

假設OP在時間戳上有一個索引,並且它是遞增的,那麼MAX()不是MIN()。 – PerformanceDBA 2011-03-07 07:40:16

+0

或者只是從'<' to '>'中修改運算符。 – Guffa 2011-03-07 12:02:22

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的解決方案,只是利用熱膨脹係數,以避免需要三角形的加入。

+0

@理查德:謝謝,修正。 – 2011-03-07 09:16:40

相關問題