我有一个表格,记录了用户在一个既有桌面应用程序又有移动应用程序的在线购物网站上的支出.(我正在学习PieCloudDB数据库)我想找出只有移动、只有桌面、既有桌面又有移动设备的用户数量和他们每天的总支出.

user_id date platform amount
1 2023-12-01 mobile 27.99
1 2023-12-01 desktop 32.68
1 2023-12-02 desktop 19.90
2 2023-12-01 mobile 83.46
2 2023-12-02 mobile 43.96
3 2023-12-01 desktop 22.00
3 2023-12-02 mobile 63.48
3 2023-12-03 mobile 28.28

结果应该是:

date platform total_amount total_users
2023-12-01 desktop 22 1
2023-12-01 mobile 83.46 1
2023-12-01 both 60.67 1
2023-12-02 desktop 19.9 1
2023-12-02 mobile 107.44 2
2023-12-02 both 0 0
2023-12-03 desktop 0 0
2023-12-03 mobile 28.28 1
2023-12-03 both 0 0

我想不出解决这个问题的办法,有人能帮我吗?

推荐答案

为此,您可以使用多个SELECT获取每天的统计数据,并使用GROUP BYHAVING子句获取平台统计数据,然后在不同的平台上应用CROSS JOIN以获得所需的输出:

with cte as (
  select date, platform, sum(total_amount) as total_amount,
                         count(total_users) as total_users
  from (
    select date, max(platform) as platform, sum(amount) as total_amount, count(distinct user_id) as total_users
    from mytable
    group by user_id, date
    having min(platform) = 'mobile' and max(platform) = 'mobile'
  union all 
    select date, max(platform) as platform, sum(amount) as total_amount, count(distinct user_id) as total_users
    from mytable
    group by user_id, date
    having min(platform) = 'desktop' and max(platform) = 'desktop'
  union all
    select date, 'both' as platform, sum(amount) as total_amount, count(distinct user_id) as total_users
    from mytable
    group by user_id, date
    having count(case when platform = 'desktop' then 1 end) + count(case when platform = 'mobile' then 1 end) = count(*)
       and count(case when platform = 'desktop' then 1 end) >= 1
       and count(case when platform = 'mobile' then 1 end) >= 1
  ) as s
  group by date, platform
),
dates as (
  select distinct date from mytable
),
platforms as (
  select 'mobile' as platform union all
  select 'desktop' union all
  select 'both'
)
select d.date, p.platform, coalesce(c.total_amount, 0) as total_amount, coalesce(c.total_users, 0) as total_users
from dates d
cross join platforms p
left join cte c on c.date = d.date and c.platform = p.platform
order by d.date, total_amount;

结果:

date        platform    total_amount    total_users
2023-12-01  desktop     22.00           1
2023-12-01  both        60.67           1
2023-12-01  mobile      83.46           1
2023-12-02  both        0               0
2023-12-02  desktop     19.90           1
2023-12-02  mobile      107.44          2
2023-12-03  both        0               0
2023-12-03  desktop     0               0
2023-12-03  mobile      28.28           1

Demo on postgresql

Sql相关问答推荐

SQL查询以创建手头的流动余额?

在SQL Server中使用LEFT连接包含特定记录

SQL是否可以计算每年的所有日期变化?

如何查询jsonb列是一个对象数组?

明细表中没有记录如何更新主表的值为0

在VB.NET中如何在MS Access数据库中创建SQL项目历史库存卡

使用多个WITH子查询的替代方法

Netezza SQL:判断两个表是否相同

将最近的结束日期与开始日期相匹配

如何根据创建日期查找两个表中最接近的记录?

错误:postgresql 中缺少表评级的 FROM 子句条目

当 2 列具有静态值并且第 3 列使用运算符 IN 时,对 PostgreSQL 和 3 列上的复杂索引的最佳查询

基于变量的条件 WHERE 子句

PostgreSQL 中将数据从 JSONB 类型转换为 Array 类型

snowflake中的动态文件名生成

正则表达式忽略特定数据部分的分隔符

在给定的日期范围内填写缺失的日期

使用其他表 SUM 的交换价格转换价格并获得 AVG

基于源表的 SQL INSERT、UPDATE 和 DELETE

pyspark 将列转换为行