2013-02-15 42 views
2

我有一個用於繪圖和數據檢查的大型數據庫。爲簡單起見,假設它看起來是這樣的:有沒有辦法在SQL中應用移動限制>

| id | day | obs | 
+----------+-----------+-----------+ 
| 1  | 500 | 4.5 | 
| 2  | 500 | 4.4 | 
| 3  | 500 | 4.7 | 
| 4  | 500 | 4.8 | 
| 5  | 600 | 5.1 | 
| 6  | 600 | 5.2 | 
       ... 

這可能是股市的數據,在這裏我們有一個測量每天多點。

我想要做的是看更長的趨勢,每天多點不必要地解決,並堵塞我的繪圖應用程序。 (我想看看30000天,每個有大約100觀察)。

有沒有辦法做這樣的事情SELECT ... LIMIT 1 PER "day"

我想我可以執行一些SELECT DISTINCT查詢,找到正確的ID,但我寧願做一些簡單的,如果它是內置的。

它如果它是每天的第一個,最後一個或平均值,則無關緊要。只是一個單一的價值。我只是喜歡什麼是最快的。

此外,我想爲Postgres,MySQL和SQLite做到這一點。我的應用程序是建立使用所有三個,我經常在它們之間切換。

謝謝!

背景:這是針對Ruby on Rails繪製應用程序的,因此ActiveRecord的一個技巧也可以工作。 https://github.com/ZachDischner/Rails-Plotter

+0

您是否只想爲每一天選擇一個值或每天的平均值? – 2013-02-15 16:37:14

+0

請參閱這裏:[如何在SQL中選擇每個組的第一/最小/最大行](http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row -per基團在-SQL /)。 – 2013-02-15 16:38:28

+0

我想我應該指定 - 但對我來說並不重要。長期趨勢可能需要隨機每日價值或平均值。平均可能只需要更多時間來執行查詢 – 2013-02-15 16:44:21

回答

3

您需要用您正在使用的RDBMS品牌標記您的問題。對Rails開發者來說,他們經常使用MySQL,但是你的問題的答案取決於這個。

對於除MySQL的所有品牌,正確的和標準的解決方案是使用窗口功能

SELECT * FROM (
    SELECT ROW_NUMBER() OVER (PARTITION BY day) AS RN, * 
    FROM stockmarketdata 
) AS t 
WHERE t.RN = 1; 

對於MySQL,不支持窗口函數的是,你可以在一種模擬它們與會話變量的笨拙方式:

SELECT * FROM (SELECT @day:=0, @r:=0) AS _init, 
(
    SELECT IF([email protected], @r:[email protected]+1, @r:=0) AS RN, @day:=day AS d, * 
    FROM stockmarketdata 
) AS t 
WHERE t.RN = 1 
+0

這太棒了!我會保持打開一兩天,看看是否有更多的答案彈出。但這正是我期待的! – 2013-02-15 17:06:09

1

你留下了很大的空間與您的語句選項:

無論它是每天的第一個,最後一個還是平均值都無關緊要。只是一個單一的價值。我只是喜歡什麼是最快的。

因此,我要離開它的ID,並首先建議每個組的obs的平均值作爲最簡單,也許是最實用的,雖然也許不是運行stat功能最快的vs vs 。限制:

MyModel.group(:day).average(:obs) 

如果你想最小:

MyModel.group(:day).minimum(:obs) 

如果你想最大:

MyModel.group(:day).maximum(:obs) 

(注意:以下兩個示例的效率低於僅輸入SQL的效率,但可能更便於攜帶。)

但你可能要三個:

ActiveRecord::Base.connection.execute(MyModel.select('MIN(obs), AVG(obs), MAX(obs)').group(:day).to_sql).to_a 

或者僅僅是數據,而散列:

ActiveRecord::Base.connection.exec_query(MyModel.select('MIN(obs), AVG(obs), MAX(obs)').group(:day).to_sql) 

如果你想中間,看到this question哪個更DB具體的,還有其他有關posts關於它,如果你搜索。

而對於更多的一些DB的像postgres有variance(...),stddev(...)built-in

最後,請查看Rails指南中的query sectionARel以獲取有關構造查詢的更多信息。例如,您可以通過firstlimit在ActiveRecord關係中進行限制,例如,在ARel中,take可讓您執行限制。子查詢也是可能的,如this question的回答所示,以及group by等也是如此。如果您與其他人共享此項目,請嘗試限制您正在使用的非可移植SQL的數量,除非您打算爲其他人添加支持數據庫,並保持這一點。

+0

感謝您的回答。這個想法也適用,但爲了加快速度,我會驗證另一個解決方案。我很感激! – 2013-02-19 16:56:55

+0

請記住,數據質量通常比速度更重要。例如,第一個或最後一個觀測數據點可能會隱藏更高或更低的值。室外溫度就是一個很好的例子。如果你只在下午進行測量,溫度往往會高於清晨。如果您只需要進行一次測量,則可能需要使用RAND()/ RANDOM()等。 – 2013-02-19 18:38:08

+0

絕對如此。我同意並讚賞意見。我將嘗試實現這兩種方法,並看看有什麼作用。以你的榜樣爲例,你是對的,臨時工在一天中都會改變。但是,如果我正在考慮長期(50年)的變化趨勢(相對而非絕對),那麼如果我在早上或下午3點錄製,則無關緊要。那就是我正在看的那種數據。感謝您的輸入! – 2013-02-20 20:04:29

相關問題