2013-04-08 54 views
2

是否有可能獲得組中前X%項的平均值?sqlite:獲得每個項目的前X%的平均值

例如:
我有一個表,它有一個item_id,時間戳和價格列。輸出應按item_id和timestamp分組,並且'price-column'應該取平均值。對於平均值,只能使用該組內最低的X%價格。

我發現了類似的問題(How to select top x records for every group),但這不適用於sqlite。

+0

「最低X%價格」是什麼意思?百分比的基礎是什麼?價錢?計數?你能舉一個例子嗎? – 2013-04-08 12:06:16

+0

按時間戳分組是否有意義?你可以用更清晰的詞語來表達你想要達成的目標 - 查詢應該返回什麼? – Tim 2013-04-08 12:51:45

+0

@Tim是的,這對我而言很有意義,因爲有許多項目具有絕對相同的時間戳(因爲它們是作爲批次插入/更新的) – Daniel 2013-04-08 13:46:41

回答

3

獲得每個組中最高的n條記錄需要計數。假設有沒有重複,下面的查詢返回的記錄數的一個項目:

select t.*, 
     (select count(*) from t t2 where t2.item_id = t.item_id 
     ) as NumPrices 
from t 

這就是所謂的相關子查詢。現在,讓我們延長了主意,包括一個等級,然後算出平均值右側組:

select item_id, avg(price) 
from (select t.*, 
      (select count(*) from t t2 where t2.item_id = t.item_id 
      ) as NumPrices, 
      (select count(*) from t t2 where t2.item_id = t.item_id and t2.price <= t.price 
      ) as PriceRank 
     from t 
    ) t 
where (100.0*PriceRank/NumPrices) <= X 
group by item_id 

爲了提高性能,你會希望在(item_id, price)的索引。

+0

我試過了 - 而查詢本身是有道理的 - 它超級慢(10分鐘後沒有完成)。我的表有〜1000000個記錄,應該被分組到〜8000條記錄。無論如何,我會接受答案 – Daniel 2013-04-08 13:49:54

+1

你有什麼指數? – 2013-04-08 14:46:08

+0

目前僅在價格欄 – Daniel 2013-04-08 21:26:06

1

要使用ID I和時間戳T得到的記錄數的組中,使用此查詢:

SELECT COUNT(*) 
FROM MyTable 
WHERE item_id = I 
    AND timestamp = T 

要得到限制,與X繁殖,並使用ROUND/CAST轉換爲整數:

SELECT CAST(ROUND(COUNT(*) * X/100) AS INTEGER) 
FROM MyTable 
WHERE item_id = I 
    AND timestamp = T 

要獲得一個特定的組是限制內的所有記錄,命令組由價格中的記錄,並限制返回的計數:

SELECT * 
FROM MyTable 
WHERE item_id = I 
    AND timestamp = T 
ORDER BY price 
LIMIT (SELECT CAST(ROUND(COUNT(*) * X/100) AS INTEGER) 
     FROM MyTable 
     WHERE item_id = I 
     AND timestamp = T) 

從理論上講,要獲得組平均值,加上GROUP BY圍繞:

SELECT item_id, 
     timestamp, 
     (SELECT AVG(price) 
     FROM (SELECT price 
       FROM MyTable T2 
       WHERE T2.item_id = T1.item_id 
       AND T2.timestamp = T1.timestamp 
       ORDER BY price 
       LIMIT (SELECT CAST(ROUND(COUNT(*) * X/100) AS INTEGER) 
        FROM MyTable T3 
        WHERE T3.item_id = T1.item_id 
         AND T3.timestamp = T1.timestamp) 
      ) 
     ) AS AvgPriceLowestX 
FROM MyTable T1 
GROUP BY item_id, 
     timestamp 

然而,似乎SQLite不容許從LIMIT子句中訪問相關的變量,因此這並在實踐中不工作。 您必須獲取所有組的ID(SELECT DISTINCT item_id, timestamp FROM MyTable)並針對每個組執行上面的第三個查詢。

在任何情況下,請確保在三列item_id,timestampprice上有一個索引以獲得良好性能。