ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

mysql – GROUP BY和自定义顺序

2019-07-10 22:15:10  阅读:823  来源: 互联网

标签:mysql sql-order-by group-by mysql-5-7 mysql-5-1


我已经阅读了MySQL order by before group by的答案,但是将它应用于我的查询最后会在子查询中找到一个子查询,这是一个相当简单的案例,所以我想知道这是否可以简化:

带有样本数据的模式

为简洁起见,我省略了成员表中的其他字段.此外,在实际应用程序中还有更多表加入,但这些表很容易加入.这是给我问题的membership_stack表.

CREATE TABLE members (
  id int unsigned auto_increment,
  first_name varchar(255) not null,
  PRIMARY KEY(id)
);

INSERT INTO members (id, first_name)
     VALUES (1, 'Tyler'),
            (2, 'Marissa'),
            (3, 'Alex'),
            (4, 'Parker');

CREATE TABLE membership_stack (
  id int unsigned auto_increment,
  member_id int unsigned not null,
  sequence int unsigned not null,
  team varchar(255) not null,
  `status` varchar(255) not null,
  PRIMARY KEY(id),
  FOREIGN KEY(member_id) REFERENCES members(id)
);

-- Algorithm to determine correct team:
-- 1. Only consider rows with the highest sequence number
-- 2. Order statuses and pick the first one found:
--    (active, completed, cancelled, abandoned)

INSERT INTO membership_stack (member_id, sequence, team, status)
     VALUES (1, 1, 'instinct', 'active'),
            (1, 1, 'valor', 'abandoned'),
            (2, 1, 'valor', 'active'),
            (2, 2, 'mystic', 'abandoned'),
            (2, 2, 'valor', 'completed'),
            (3, 1, 'instinct', 'completed'),
            (3, 2, 'valor', 'active');

我无法更改数据库架构,因为数据与外部数据源同步.

询问

这是我到目前为止:

    SELECT m.id, m.first_name, ms.sequence, ms.team, ms.status
      FROM membership_stack AS ms
      JOIN (
    SELECT member_id, MAX(sequence) AS sequence
      FROM membership_stack
  GROUP BY member_id
           ) AS t1
        ON ms.member_id = t1.member_id
       AND ms.sequence = t1.sequence
RIGHT JOIN members AS m
        ON ms.member_id = m.id
  ORDER BY m.id, FIELD(ms.status, 'active', 'completed', 'cancelled', 'abandoned');

这可以按预期工作,但如果他们的“最近序列”涉及多个团队,则成员可能会多次出现.我需要做的是再次在id上聚合并选择每个组中的FIRST行.

然而,这会带来一些问题:

>有no FIRST() function in MySQL
>这整个结果集将成为子表(子查询),这在这里不是什么大问题,但查询在应用程序上非常大.
>它需要与ONLY_FULL_GROUP_BY mode兼容,因为它在MySQL 5.7上默认启用.我没有检查但是我怀疑FIELD(ms.status,’active’,’completed’,’cancel’,’abandoned’)被认为是这个结果集的功能依赖字段.该查询还需要与MySQL 5.1兼容,因为这是我们目前正在运行的.

目标

| id | first_name | sequence |     team |    status |
|----|------------|----------|----------|-----------|
|  1 |      Tyler |        1 | instinct |    active |
|  2 |    Marissa |        2 |    valor | completed |
|  3 |       Alex |        2 |    valor |    active |
|  4 |     Parker |     NULL |     NULL |      NULL |

我该怎么办?

编辑:我注意到有些成员不属于任何团队.这些成员应包含在结果集中,并为这些字段使用空值.更新问题以反映新信息.

解决方法:

您可以在WHERE子句中使用LIMIT 1的相关子查询:

SELECT m.id, m.first_name, ms.sequence, ms.team, ms.status
FROM members AS m
JOIN membership_stack AS ms ON ms.member_id = m.id
WHERE ms.id = (
    SELECT ms1.id
    FROM membership_stack AS ms1
    WHERE ms1.member_id = ms.member_id
    ORDER BY ms1.sequence desc, 
             FIELD(ms1.status, 'active', 'completed', 'cancelled', 'abandoned'),
             ms1.id asc
    LIMIT 1
)
ORDER BY m.id;

演示:http://rextester.com/HGU18448

更新

要包含membership_stack表中没有条目的成员,您应该使用LEFT JOIN,并将子查询条件从WHERE子句移动到ON子句:

SELECT m.id, m.first_name, ms.sequence, ms.team, ms.status
FROM members AS m
LEFT JOIN membership_stack AS ms 
    ON  ms.member_id = m.id
    AND ms.id = (
        SELECT ms1.id
        FROM membership_stack AS ms1
        WHERE ms1.member_id = ms.member_id
        ORDER BY ms1.sequence desc, 
                 FIELD(ms1.status, 'active', 'completed', 'cancelled', 'abandoned'),
                 ms1.id asc
        LIMIT 1
    )
ORDER BY m.id;

演示:http://rextester.com/NPI79503

标签:mysql,sql-order-by,group-by,mysql-5-7,mysql-5-1
来源: https://codeday.me/bug/20190710/1428347.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有