mysql - MySQL 销售报告
问题描述
我有以下表格:
users
+-------+-----------+-----------+
| id | source | age_group |
+-------+-----------+-----------+
| 1 | google | 18 - 22 |
+-------+-----------+-----------+
| 2 | facebook | 22 - 25 |
+-------+-----------+-----------+
| 3 | site | 25 - 35 |
+-------+-----------+-----------+
| 4 | google | 25 - 35 |
+-------+-----------+-----------+
| 5 | google | 18 - 22 |
+-------+-----------+-----------+
orders
+-------+-----------+
| id | userId |
+-------+-----------+
| 1 | 3 |
+-------+-----------+
| 2 | 1 |
+-------+-----------+
| 3 | 3 |
+-------+-----------+
| 4 | 2 |
+-------+-----------+
| 5 | 4 |
+-------+-----------+
| 6 | 5 |
+-------+-----------+
orders_payments:
+-------+-----------+-----------+
| id | orderId | amount |
+-------+-----------+-----------+
| 1 | 1 | 10 |
+-------+-----------+-----------+
| 2 | 2 | 0 |
+-------+-----------+-----------+
| 3 | 3 | 40 |
+-------+-----------+-----------+
| 4 | 5 | 0 |
+-------+-----------+-----------+
| 5 | 6 | 0 |
+-------+-----------+-----------+
和 3 种可能性:
- 用户下单并付款(orders_payments 金额 > 0)
- 用户免费试用了一项服务(orders_payments 金额 = 0)
- 用户下订单但没有出现(orders_payments 中没有记录)
我需要一个看起来像这样的销售报告:
+-----------+-----------+-----------+-----------+-----------+
| source | age_group | paid | tried | no_show |
+-----------+-----------+-----------+-----------+-----------+
| google | 18 - 22 | 0 | 2 | 0 |
+-----------+-----------+-----------+-----------+-----------+
| google | 25 - 35 | 0 | 1 | 0 |
+-----------+-----------+-----------+-----------+-----------+
| facebook | 22 - 25 | 0 | 0 | 1 |
+-----------+-----------+-----------+-----------+-----------+
| site | 25 - 35 | 1 | 0 | 0 |
+-----------+-----------+-----------+-----------+-----------+
最后 3 列代表至少付费一次、免费试用服务或未出席预约的用户数量。
报告按来源分组,然后按年龄组。所以像这样
SELECT source, age_group, ... FROM users GROUP BY source, age_group
对于我的一生,我无法弄清楚。
任何想法都非常感谢。
谢谢!
LE:我只想统计一次用户。因此,如果他们有两个已付款订单,我将它们计为已付款一次,如果尝试但随后已付款,我也想将它们计为已付款一次,依此类推。
LE2:我认为这是一个可能的解决方案:
select
u.source,
u.age_group,
sum(op.amount > 0) paid,
sum(op.amount = 0) tried,
sum(op.orderId is null) no_show
from users u
inner join orders o on o.userId = u.id
left join (
select max(amount) as amount, orderId
from orders_payments
left join orders on orders_payments.orderId = orders.id
group by orders.userId
) op on op.orderId = o.id
group by u.source, u.age_group
order by u.source, u.age_group
解决方案
我会left join
在支付表上选择一个,然后是条件聚合。
select
u.source,
u.age_group,
sum(op.amount > 0) paid,
sum(op.amount = 0) tried,
sum(op.orderId is null) no_show
from users u
inner join orders o on o.userId = u.id
left join orders_payments op on op.orderId = o.id
group by u.source, u.age_group
order by u.source, u.age_group
推荐阅读
- php - PHP - 使用 json 中的 id 重定向
- c# - 如何在 C# 中制作按键表单事件
- react-native - Admob 插页式广告未关闭。反应原生
- python - Tkinter 条目:如何仅在第一次单击时删除默认条目文本?
- amazon-web-services - AWS CloudWatch - 转到搜索词的第一次出现
- javascript - 将 vuejs 中的数组存储到 SQL 列 json 中,但存储 null
- python - 为什么我的 Microsoft Azure 使用详情 API propterties.cost 总和会波动?
- python - PowerShell 与程序(控制面板)
- java - 使用来自客户端 Itext 的外部签名签署 pdf
- c# - WCF RESTful 应用程序 PUT、POST、DELETE 收到相同的错误:“该方法不允许。”