我有一个简单的问题,但我想知道是否有人能告诉我窗口函数中DISTINCT和GROUP BY背后的机制.

我已经读了几篇帖子,但没有得到任何与我的怀疑有关的帖子.

我的问题是:

关于以下输入/输出: enter image description here

这是通过以下SQL查询得出的:

select
player_id
, first_value(event_date) over(partition by player_id order by event_date) as first_login
from Activity
group by player_id

我知道它可以通过简单的聚合来解决,不要误会我的意思. 我只是想知道为什么‘group by’在这个问题上似乎不起作用,而‘DISTINCT’可以起作用并通过测试.提前谢谢您.

select
DISTINCT player_id
, first_value(event_date) over(partition by player_id order by event_date) as first_login
from Activity

如果我使用cuit或子查询,则‘group by’起作用:

select
*
from
(select
player_id
, first_value(event_date) over(partition by player_id order by event_date) as first_login
from Activity) as cte
group by player_id, first_login

虚拟数据

WITH 
Activity AS (
    SELECT 1 AS player_id, 2 AS device_id, '2016-03-01' AS event_date, 5 AS games_played UNION ALL
    SELECT 1, 2, '2016-05-02', 6 UNION ALL
    SELECT 1, 3, '2015-06-25', 1 UNION ALL
    SELECT 3, 1, '2016-03-02', 0 UNION ALL
    SELECT 3, 4, '2016-02-03', 5 )

推荐答案

对查询之间的差异的解释是,操作是有顺序的.

  1. GROUP BY将行减少到分组列(player_id)中的每个值一行.在您的示例中,这将导致错误的值‘2016-03-01’,它不是最小值,它只是在执行过程中读取的第一行的值.此错误是因为您没有使用sql_mode=ONLY_FULL_GROUP_BY.
  2. 窗口函数适用于聚合后的行.如果使用按与分组列相同的列进行分区的窗口函数,则根据定义,分区是单行.
  3. DISTINCT应用于窗口函数之后,将行减少到具有唯一值组合的行.这消除了重复行.

Mysql相关问答推荐

完全相同的A B表达在SQL中的不同上下文中意外返回不同的结果

如何将MySQL与AS&Quot;语法一起用于存储过程返回的表?

MySQL:统计单词在单元格中出现的次数,并将数字放在bra中单词的旁边

我可以指示MariaDB-Install-db和MariaDB忽略配置中的用户设置吗?

根据SQL中的平均范围对学生进行排名

Select 并统计所有条目并根据条目对它们进行分组

高效的 SQL 查询,用于计算半小时时间序列中已发生的行的一部分

Select 最高等级最多的部门名称

java.lang.NullPointerException:无法调用com.proj.my.repository.OrderRepository.save(Object),因为this.orderRepository为空

过滤查询结果

为什么一个 10 位的电话号码不能存储在长度为 10 的整数中?

为什么这个 NOT NULL 到 NULL 迁移会触发大量 I/O 操作?

用两个新列制作表格,按偶数或奇数对另一列进行分类,并将一个类别中的所有偶数和奇数相加

使用带有 ELSEIF 和 ELSE 的 3 列更新问题

为什么 ORDER BY 'id' 'desc' 不返回语法错误?

如何按给定开始日期和结束日期的月份汇总?

PHP PDO 与普通 mysql_connect

Python MYSQL 更新语句

警告:mysqli_connect(): (HY000/1045): Access denied for user 'username'@'localhost' (using password: YES)

我可以在 PHP 中使用 PDO 创建数据库吗?