使用 array_agg 和结构后如何在列中查找值?
How to find a value in a column after I've used array_agg and struct?
在我的数据库中使用以下代码后,我得到了以下结果:
select USERID,
array_agg(struct(ORDER_TIME, DELIVERY_TIME, PLATFORM) order by ORDER_TIME) STATS
from `project.dataset.table`
group by USERID
having count(1) > 1
order by USERID
用户名
STATS.ORDER_TIME
STATS.DELIVERY_TIME
STATS.PLATFORM
011
2021-01-0911:14:18
2021-01-0911:44:01
手机
2021-02-1216:15:51
2021-02-1217:16:51
桌面
2021-03-30 17:23:45
2021-02-1217:16:51
桌面
033
2021-01-01 12:30:14
2021-01-0113:30:00
手机
2021-04-1623:00:45
2021-04-1623:45:40
手机
040
2021-02-18 19:22:55
2021-02-18 20:00:05
手机
2021-05-0609:12:13
2021-05-0610:00:10
桌面
但是,我只需要那些同时包含移动和桌面的寄存器。所以我需要这样的东西,结果是没有 USERID 040 的数据,因为他们只在手机上订购 phone:
用户名
STATS.ORDER_TIME
STATS.DELIVERY_TIME
STATS.PLATFORM
011
2021-01-0911:14:18
2021-01-0911:44:01
手机
2021-02-1216:15:51
2021-02-1217:16:51
桌面
2021-03-30 17:23:45
2021-02-1217:16:51
桌面
033
2021-01-01 12:30:14
2021-01-0113:30:00
手机
2021-05-0609:12:13
2021-05-0610:00:10
桌面
我怎么可能那样做?非常感谢!
“最简单”的方法是在 having
子句中再添加几个条件
select USERID, array_agg(struct(ORDER_TIME, DELIVERY_TIME, PLATFORM) order by ORDER_TIME) STATS
from `project.dataset.table`
group by USERID
having count(1) > 1
and 'mobile' in unnest(array_agg(PLATFORM))
and 'desktop' in unnest(array_agg(PLATFORM))
order by USERID
如果应用于您问题中的示例数据 - 输出为
如果您有更多此类条目要比较 - 您可以使用以下版本以避免重复类似的代码行
select USERID, array_agg(struct(ORDER_TIME, DELIVERY_TIME, PLATFORM) order by ORDER_TIME) STATS
from `project.dataset.table`
group by USERID
having count(1) > 1
and array_length(array_agg(distinct if(PLATFORM in ('mobile', 'desktop'), PLATFORM, null))) = 2
order by USERID
在我的数据库中使用以下代码后,我得到了以下结果:
select USERID,
array_agg(struct(ORDER_TIME, DELIVERY_TIME, PLATFORM) order by ORDER_TIME) STATS
from `project.dataset.table`
group by USERID
having count(1) > 1
order by USERID
用户名 | STATS.ORDER_TIME | STATS.DELIVERY_TIME | STATS.PLATFORM |
---|---|---|---|
011 | 2021-01-0911:14:18 | 2021-01-0911:44:01 | 手机 |
2021-02-1216:15:51 | 2021-02-1217:16:51 | 桌面 | |
2021-03-30 17:23:45 | 2021-02-1217:16:51 | 桌面 | |
033 | 2021-01-01 12:30:14 | 2021-01-0113:30:00 | 手机 |
2021-04-1623:00:45 | 2021-04-1623:45:40 | 手机 | |
040 | 2021-02-18 19:22:55 | 2021-02-18 20:00:05 | 手机 |
2021-05-0609:12:13 | 2021-05-0610:00:10 | 桌面 |
但是,我只需要那些同时包含移动和桌面的寄存器。所以我需要这样的东西,结果是没有 USERID 040 的数据,因为他们只在手机上订购 phone:
用户名 | STATS.ORDER_TIME | STATS.DELIVERY_TIME | STATS.PLATFORM |
---|---|---|---|
011 | 2021-01-0911:14:18 | 2021-01-0911:44:01 | 手机 |
2021-02-1216:15:51 | 2021-02-1217:16:51 | 桌面 | |
2021-03-30 17:23:45 | 2021-02-1217:16:51 | 桌面 | |
033 | 2021-01-01 12:30:14 | 2021-01-0113:30:00 | 手机 |
2021-05-0609:12:13 | 2021-05-0610:00:10 | 桌面 |
我怎么可能那样做?非常感谢!
“最简单”的方法是在 having
子句中再添加几个条件
select USERID, array_agg(struct(ORDER_TIME, DELIVERY_TIME, PLATFORM) order by ORDER_TIME) STATS
from `project.dataset.table`
group by USERID
having count(1) > 1
and 'mobile' in unnest(array_agg(PLATFORM))
and 'desktop' in unnest(array_agg(PLATFORM))
order by USERID
如果应用于您问题中的示例数据 - 输出为
如果您有更多此类条目要比较 - 您可以使用以下版本以避免重复类似的代码行
select USERID, array_agg(struct(ORDER_TIME, DELIVERY_TIME, PLATFORM) order by ORDER_TIME) STATS
from `project.dataset.table`
group by USERID
having count(1) > 1
and array_length(array_agg(distinct if(PLATFORM in ('mobile', 'desktop'), PLATFORM, null))) = 2
order by USERID