グループ内の上位 X% アイテムの平均を取得することは可能ですか?
例:
item_id、timestamp、price 列を持つテーブルがあります。出力は item_id とタイムスタンプでグループ化され、「価格列」が平均化されます。平均化には、そのグループ内の最低 X% 価格のみを使用する必要があります。
同様の質問 (グループごとに上位 x レコードを選択する方法) を見つけましたが、これは sqlite では機能しません。
グループ内の上位 X% アイテムの平均を取得することは可能ですか?
例:
item_id、timestamp、price 列を持つテーブルがあります。出力は item_id とタイムスタンプでグループ化され、「価格列」が平均化されます。平均化には、そのグループ内の最低 X% 価格のみを使用する必要があります。
同様の質問 (グループごとに上位 x レコードを選択する方法) を見つけましたが、これは sqlite では機能しません。
各グループ内の上位 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)
。
グループ内のレコード数を IDI
とタイムスタンプ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
)、各グループに対して上記の 3 番目のクエリを実行する必要があります。
いずれにせよ、良好なパフォーマンスを得るにitem_id
は、 、timestamp
、およびの 3 つの列に 1 つのインデックスがあることを確認してください。price