我有一个带有person个表的MySQL数据库,我在其中存储用户的个人详细信息.每个用户都属于一个组,所以我有另一个member_group表,其中我根据他们的组ID存储他们的用户ID,以及他们的in_group_begin日期和(最终)他们的in_group_end日期.

当用户在组中时,in_group_end值为NULL.当他们离开该组时,它将填充离开日期.然后,它们可能会永远消失,或者只是移动到另一个组,从而需要在member_group表中增加一行.

  • 因此,刚刚加入的汤姆可能在member_group人中有一项记录 in_group_end值为空的表.
  • 迪克可能已经在这里有一段时间了,在member_group表中有四条记录,其中 除最新版本外,所有版本中填充的值均为in_group_end.
  • 哈里已经离开了-他是member_group表中的两条记录,in_group_end列中填充了一个值 对他们所有人来说.

我现在希望查询Person表并返回我的用户的列表,如果是当前用户,则返回他们当前的组ID;如果是过go 的用户,则返回他们所在的最后一个组ID.

我假设这可以在子查询中解决,但我不确定如何排序(例如ORDER BY (in_group_end = NULL) DESC, in_group_end DESC)和GROUP BY,这无论如何都会预先执行.member_group表有一个自动递增的tbl_id字段,因此可能会在MAX(tbl_id)上进行某种进一步的联接或其他操作?

这个查询会是什么样子的?如果有任何帮助,我很感激.

推荐答案

您可以使用FIRST_VALUE()窗口函数:

SELECT DISTINCT user_id,
       FIRST_VALUE(group_id) OVER (
         PARTITION BY user_id 
         ORDER BY in_group_end IS NULL DESC, in_group_end DESC
       ) AS last_group_id
FROM member_group;

如果您想要了解用户的所有详细信息:

WITH cte AS (
    SELECT DISTINCT user_id,
           FIRST_VALUE(group_id) OVER (
             PARTITION BY user_id 
             ORDER BY in_group_end IS NULL DESC, in_group_end DESC
           ) AS last_group_id
    FROM member_group
)
SELECT p.*, c.last_group_id
FROM person AS p LEFT JOIN cte AS c -- LEFT join just in case a person was never a member of any group
ON c.user_id = p.user_id;

如果您还想要最后一个in_group_end值,则使用row_number()窗口函数会更容易:

WITH cte AS (
    SELECT *,
           ROW_NUMBER() OVER (
             PARTITION BY user_id 
             ORDER BY in_group_end IS NULL DESC, in_group_end DESC
           ) AS rn
    FROM member_group
)
SELECT p.*, 
       c.user_id, c.in_group_end, c.group_id AS last_group_id
FROM person AS p LEFT JOIN cte AS c -- LEFT join just in case a person was never a member of any group
ON c.user_id = p.user_id AND c.rn = 1;

Mysql相关问答推荐

MySQL INSERT INSERT ON DIPLICATE KEY UPDATE WITH COMPAY PRIMARY KEY失败

筛选器中的Case When语句

MySQL binlog事件上的并发事务行为

SQL/Pyspark -判断条件

使用字符串文字与使用日期文字时的SQL行为

将上传文件的存储路径放在一张表中的缺点是什么?

生成json数据并根据特定表的匹配条件进行过滤

带有 JOIN 和 WHERE 子句的 INSERT 语句

如何解码存储在带有type*:前缀的base64中的数据?

为生日创建 MySQL 索引

如何在 axios 请求中将更新的设置状态值作为参数传递

分别针对每个不同的列 Select 聚合

在 Codeigniter MySQL 中从另一个数据库获取数据

如何获取从开始时间到结束时间的所有正在运行的作业(job)的总和?

即使我的约束是正确的,如何解决 errno: 150 外键约束形成错误?

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

在 MySQL 中重命名外键列

在另一个 where 语句(子查询?)中使用一个 sql 查询的结果

我的 PDO 声明不起作用

MySQL与空值比较