【问题标题】:mysql self join based enum valuesmysql 基于自连接的枚举值
【发布时间】:2013-01-29 17:02:49
【问题描述】:

如何使用自联接根据枚举状态获取计数

我有一个名为“student”的表,其中我使用枚举表示状态 0、1、2,其中 0 表示非活动,1 表示活动,2 表示已删除。

那是

studentid studentenrollid studentname studentstatus

1          3                 xyz          1

2          3                 xyz          2

3          8                 asda         1

4          7                 sdd          1

5          9                 asds         0

6          3                 xyz          1

我需要根据 studentrollid 唯一的状态获取计数。

studentrollid | inactive | active | deleted

    3            0           2        1

    8            0           1        0

    7            0           1        0

    9            1           0        0

【问题讨论】:

    标签: mysql join pivot self-join


    【解决方案1】:

    请试试这个:

    SQLFIDDLE DEMO

    select studentenrollid,
    sum(case when studentstatus = 1 then 1
        else 0 end) as Active, 
    sum(case when studentstatus = 0 then 1
        else 0 end) as Inactive, 
    sum(case when studentstatus = 2 then 1
        else 0 end) as Deleted
    from demo
    group by studentenrollid
    ;
    
    | STUDENTENROLLID | ACTIVE | INACTIVE | DELETED |
    -------------------------------------------------
    |               3 |      2 |        0 |       1 |
    |               7 |      1 |        0 |       0 |
    |               8 |      1 |        0 |       0 |
    |               9 |      0 |        1 |       0 |
    

    Another shorter query:

    select a.studentenrollid,
    sum(a.studentstatus = 1) as Active, 
    sum(a.studentstatus = 0) as Inactive,
    sum(a.studentstatus = 2) as Deleted 
    from demo a
    group by a.studentenrollid
    ;
    
    | STUDENTENROLLID | ACTIVE | INACTIVE | DELETED |
    -------------------------------------------------
    |               3 |      2 |        0 |       1 |
    |               7 |      1 |        0 |       0 |
    |               8 |      1 |        0 |       0 |
    |               9 |      0 |        1 |       0 |
    

    MYSQL 5.1.61 version query


    基于 OP 在 cmets 中给出的 create statment/insert 语句:

    SQLFIDDEL DEMO 2

    | STUDENTENROLLID | ACTIVE | INACTIVE | DELETED |
    -------------------------------------------------
    |               1 |      1 |        0 |       0 |
    |               2 |      1 |        0 |       0 |
    |               3 |      1 |        0 |       0 |
    |              41 |      9 |        1 |       1 |
    

    【讨论】:

    【解决方案2】:

    您可以使用带有 CASE 表达式的聚合函数来透视数据:

    select studentenrollid,
      count(case when studentstatus = '0' then studentid end) InActive,
      count(case when studentstatus = '1' then studentid end) Active,
      count(case when studentstatus = '2' then studentid end) Deleted
    from yourtable
    group by studentenrollid
    

    SQL Fiddle with Demo

    结果是:

    | STUDENTENROLLID | INACTIVE | ACTIVE | DELETED |
    -------------------------------------------------
    |               3 |        0 |      2 |       1 |
    |               7 |        0 |      1 |       0 |
    |               8 |        0 |      1 |       0 |
    |               9 |        1 |      0 |       0 |
    

    使用您放置在 cmets 中的示例数据编辑 #1:

    CREATE TABLE IF NOT EXISTS demo 
    ( 
      studentid int(11) NOT NULL AUTO_INCREMENT, 
      studentenrollid int(11) NOT NULL, 
      studentstatus enum('0','1','2') NOT NULL DEFAULT '1', 
      PRIMARY KEY (studentid), 
      KEY studentenrollid (studentenrollid) 
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=84 ;
    
    
    INSERT INTO demo (studentid, studentenrollid, studentstatus) 
    VALUES
    (22, 41, '2'),
    (23, 1,'1'),
    (24, 2, '1'),
    (25, 3, '1'),
    (26, 41, '1'),
    (29, 41, '1'),
    (30, 41, '1'),
    (31, 41, '1'),
    (32, 41, '1'),
    (33, 41, '1'),
    (34, 41,'1'),
    (35, 41, '1'),
    (36, 41, '1'),
    (37, 41, '1') 
    

    您的查询将是:

    select studentenrollid,
      count(case when studentstatus = '0' then studentid end) InActive,
      count(case when studentstatus = '1' then studentid end) Active,
      count(case when studentstatus = '2' then studentid end) Deleted
    from demo
    group by studentenrollid
    

    结果(见SQL Fiddle with Demo):

    | STUDENTENROLLID | INACTIVE | ACTIVE | DELETED |
    -------------------------------------------------
    |               1 |        0 |      1 |       0 |
    |               2 |        0 |      1 |       0 |
    |               3 |        0 |      1 |       0 |
    |              41 |        0 |     10 |       1 |
    

    请注意,您只会得到一个已删除的计数,因为这是您在数据库中拥有的唯一值(至少在示例数据中)。

    【讨论】:

    • @user2018795 如果您使用的是 mysql 5.1,这应该可以看到这个演示 -- sqlfiddle.com/#!8/028df
    • @user2018795 查看我的编辑,查询按预期工作。您放置在 cmets 中的样本数据仅包含已删除的记录,因此您将仅返回这些计数。使用您的样本数据时,结果是相同的。
    • 41(STUDENTENROLLID)有11条记录,其中1条记录被删除(studentstatus = 2),其余记录为(studentstatus = 1)
    • @user2018795 现在应该已修复。请参阅我的编辑。它将studentstatus 值解释为字符串而不是整数
    猜你喜欢
    • 1970-01-01
    • 2014-09-16
    • 2010-10-12
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    • 2021-07-22
    • 2012-11-11
    • 1970-01-01
    相关资源
    最近更新 更多