使用 SQL,为 table 中的每个用户计算最近 n 次购买的平均值
Find the average over the n last purchases, for every user in the table using SQL
我有一个 SQLite 数据库,有两个 tables:
用户
用户ID
字段 1
字段 2
字段 3
字段 4
1
2
3
购买
购买编号
用户ID
价格
时间戳
1
2
70
5166323
2
1
30
6543654
3
1
100
5456434
4
2
30
5846541
5
2
40
9635322
6
1
50
2541541
我想写一个 SQL 查询 returns 一个 table
用户ID
字段 1
字段 2
字段 3
字段 4
平均价格
1
2
3
其中 avgPrice 对应于用户最近 n 次购买的平均价格。
我设法编写了以下查询,计算每个用户购买的平均价格:
SELECT
users.userID,
users.field1,
users.field2,
users.field3,
users.field4,
avg(purchases.price)
FROM purchases
JOIN users on users.userID = purchases.userID
GROUP BY purchases.userID
但我想不出任何有效的方法来计算最近 n 次购买的平均值。 (我能找到的唯一方法涉及内部查询并且效率非常低)。
非常感谢你帮助解决这个问题。
(仅供参考,这里的 tables 是我实际使用的 tables 的简化版本)。
您可以使用ROW_NUMBER()
window 函数从最后一个开始对购买进行排序,然后加入table users
聚合:
SELECT u.*, COALESCE(AVG(p.price), 0) avgPrice
FROM users u
LEFT JOIN (
SELECT *, ROW_NUMBER() OVER (PARTITION BY userID ORDER BY timestamp DESC) rn
FROM purchases
) p ON p.userID = u.userID AND p.rn <= ?
GROUP BY u.userID
将 ?
更改为您想要的数字 n。
您可以为此使用相关子查询:
SELECT u.*,
(SELECT AVG(p.price)
FROM (SELECT p.price
FROM purchases p
WHERE p.userID = u.userID
ORDER BY p.timestamp DESC
LIMIT ? -- whatever number you wnat
) p
) as avg_price
FROM users u;
为了性能,您需要 purchases(userID, timestamp desc, price)
上的索引。
我有一个 SQLite 数据库,有两个 tables:
用户
用户ID | 字段 1 | 字段 2 | 字段 3 | 字段 4 |
---|---|---|---|---|
1 | ||||
2 | ||||
3 |
购买
购买编号 | 用户ID | 价格 | 时间戳 |
---|---|---|---|
1 | 2 | 70 | 5166323 |
2 | 1 | 30 | 6543654 |
3 | 1 | 100 | 5456434 |
4 | 2 | 30 | 5846541 |
5 | 2 | 40 | 9635322 |
6 | 1 | 50 | 2541541 |
我想写一个 SQL 查询 returns 一个 table
用户ID | 字段 1 | 字段 2 | 字段 3 | 字段 4 | 平均价格 |
---|---|---|---|---|---|
1 | |||||
2 | |||||
3 |
其中 avgPrice 对应于用户最近 n 次购买的平均价格。
我设法编写了以下查询,计算每个用户购买的平均价格:
SELECT
users.userID,
users.field1,
users.field2,
users.field3,
users.field4,
avg(purchases.price)
FROM purchases
JOIN users on users.userID = purchases.userID
GROUP BY purchases.userID
但我想不出任何有效的方法来计算最近 n 次购买的平均值。 (我能找到的唯一方法涉及内部查询并且效率非常低)。
非常感谢你帮助解决这个问题。 (仅供参考,这里的 tables 是我实际使用的 tables 的简化版本)。
您可以使用ROW_NUMBER()
window 函数从最后一个开始对购买进行排序,然后加入table users
聚合:
SELECT u.*, COALESCE(AVG(p.price), 0) avgPrice
FROM users u
LEFT JOIN (
SELECT *, ROW_NUMBER() OVER (PARTITION BY userID ORDER BY timestamp DESC) rn
FROM purchases
) p ON p.userID = u.userID AND p.rn <= ?
GROUP BY u.userID
将 ?
更改为您想要的数字 n。
您可以为此使用相关子查询:
SELECT u.*,
(SELECT AVG(p.price)
FROM (SELECT p.price
FROM purchases p
WHERE p.userID = u.userID
ORDER BY p.timestamp DESC
LIMIT ? -- whatever number you wnat
) p
) as avg_price
FROM users u;
为了性能,您需要 purchases(userID, timestamp desc, price)
上的索引。