sql – 考虑组中的每个id的单个记录

背景

我有一个包含4列的sql表:

> id – varchar(50)
> g1 – varchar(50)
> g2 – varchar(50)
> datetime – 时间戳

我有这个问题:

SELECT g1,COUNT(DISTINCT id),SUM(COUNT(DISTINCT id)) OVER () AS total,(CAST(COUNT(DISTINCT id) AS float) / SUM(COUNT(DISTINCT id)) OVER ()) AS share
FROM my_table
and g2 = 'start'
GROUP BY 1
order by share desc

构建此查询是为了回答:用户中g1值的分布是什么?

问题

每个id可能在表中有多个记录.我想考虑最早的一个.早期意味着,最小日期时间值.

id    g1    g2      datetime
x1    a     start   2016-01-19 21:01:22
x1    c     start   2016-01-19 21:01:21
x2    b     start   2016-01-19 09:03:42
x1    a     start   2016-01-18 13:56:45

实际查询结果

g1  count   total   share
a   2       4       0.5
b   1       4       0.25
c   1       4       0.25

我们有4条记录,但我只想考虑两条记录:

x2    b     start   2016-01-19 09:03:42
x1    a     start   2016-01-18 13:56:45

这是每个id最早的记录.

预期的查询结果

g1  count   total   share
a   1       2       0.5
b   1       2       0.5

我如何仅考虑组中每个id的最早记录

解决方法

您正在查询my_table的所有数据,尽管您只想拥有最早的id日期.我假设id是表中的主键.

我建议您定义一个视图(或内联视图),它只查询id的最早日期,并在该视图上使用您的查询而不是my_table.

视图可以定义为如此,并且只包含最早日期的id:

select * from my_table a 
where a.datetime = (select min(z.datetime) from my_table z where a.id = z.id) and a.g2 = 'start'

您可以将其定义为视图或直接使用它,如下所示:

SELECT g1,(CAST(COUNT(DISTINCT id) AS float) / SUM(COUNT(DISTINCT id)) OVER ()) AS share
FROM (select a.id,a.g1,a.g2,a.datetime from my_table a where a.datetime = (select min(z.datetime) from my_table z where a.id = z.id) and a.g2 = 'start')
GROUP BY 1
order by share desc

相关文章

(一)日志传送架构 (1.1)相关服务器 主服务器 :用于生产的服务器,上面运行这生产SQL Server数据库...
(一)事故背景 最近在SQL Server 2012生产数据库上配置完事物复制(发布订阅)后,生产数据库业务出现了...
(一)测试目的 目前公司使用的SQL SERVER 2012高可用环境为主备模式,其中主库可执行读写操作,备库既...
(一)背景个人在使用sql server时,用到了sql server的发布订阅来做主从同步,类似MySQL的异步复制。在...
UNION和OR谓词 找出 product 和 product2 中售价高于 500 的商品的基本信息. select * from product wh...
datawhale组队学习task03