• MYSQL-实现ORACLE- row_number() over(partition by ) 分组排序功能


    MYSQL-实现ORACLE- row_number() over(partition by ) 分组排序功能

      由于MYSQL没有提供类似ORACLE中OVER()这样丰富的分析函数. 所以在MYSQL里需要实现这样的功能,我们只能用一些灵活的办法:

    1.首先我们来创建实例数据:

    drop table if exists heyf_t10;
    create table heyf_t10 (empid int ,deptid int ,salary decimal(10,2) );
    
    insert into heyf_t10 values
    (1,10,5500.00),
    (2,10,4500.00),
    (3,20,1900.00),
    (4,20,4800.00),
    (5,40,6500.00),
    (6,40,14500.00),
    (7,40,44500.00),
    (8,50,6500.00),
    (9,50,7500.00);

    2. 确定需求: 根据部门来分组,显示各员工在部门里按薪水排名名次.

    显示结果预期如下:

    +-------+--------+----------+------+
    | empid | deptid | salary   | rank |
    +-------+--------+----------+------+
    |     1 |     10 |  5500.00 |    1 |
    |     2 |     10 |  4500.00 |    2 |
    |     4 |     20 |  4800.00 |    1 |
    |     3 |     20 |  1900.00 |    2 |
    |     7 |     40 | 44500.00 |    1 |
    |     6 |     40 | 14500.00 |    2 |
    |     5 |     40 |  6500.00 |    3 |
    |     9 |     50 |  7500.00 |    1 |
    |     8 |     50 |  6500.00 |    2 |
    +-------+--------+----------+------+
    9 rows in set (0.00 sec)

    3. SQL 实现

    SELECT
        empid,
        deptid,
        salary,
        rank
    FROM
        (
            SELECT
                empid,
                deptid,
                salary,
    
            IF (
                @pdept = src.deptid ,@rank := @rank + 1 ,@rank := 1
            ) AS rank,
            @pdept := src.deptid AS g
        FROM
            (
                SELECT
                    empid,
                    deptid,
                    salary
                FROM
                    heyf_t10
                ORDER BY
                    deptid ASC,
                    salary DESC
            ) src,
            (
                SELECT
                    @pdept := NULL ,@rank := 0
            ) var
        ) z;

    4. 结果演示

    mysql> SELECT
        ->  empid,
        ->  deptid,
        ->  salary,
        ->  rank
        -> FROM
        ->  (
        ->          SELECT
        ->                  empid,
        ->                  deptid,
        ->                  salary,
        ->
        ->          IF (
        ->                  @pdept = src.deptid ,@rank := @rank + 1 ,@rank := 1
        ->          ) AS rank,
        ->          @pdept := src.deptid AS g
        ->  FROM
        ->          (
        ->                  SELECT
        ->                          empid,
        ->                          deptid,
        ->                          salary
        ->                  FROM
        ->                          heyf_t10
        ->                  ORDER BY
        ->                          deptid ASC,
        ->                          salary DESC
        ->          ) src,
        ->          (
        ->                  SELECT
        ->                          @pdept := NULL ,@rank := 0
        ->          ) var
        ->  ) z;
    +-------+--------+----------+------+
    | empid | deptid | salary   | rank |
    +-------+--------+----------+------+
    |     1 |     10 |  5500.00 |    1 |
    |     2 |     10 |  4500.00 |    2 |
    |     4 |     20 |  4800.00 |    1 |
    |     3 |     20 |  1900.00 |    2 |
    |     7 |     40 | 44500.00 |    1 |
    |     6 |     40 | 14500.00 |    2 |
    |     5 |     40 |  6500.00 |    3 |
    |     9 |     50 |  7500.00 |    1 |
    |     8 |     50 |  6500.00 |    2 |
    +-------+--------+----------+------+
    9 rows in set (0.00 sec)

     我的SQL:

    SELECT
        MESSAGE_ID,
        GET_USER_ID,
        SEND_USER_ID,
        MESSAGE_CONTEXT,
        CREATE_TIME
    FROM
        (
            SELECT
                SRC.*,
            IF (
                @V_USER_ID = USER_ID ,@V_RANK := @V_RANK + 1 ,@V_RANK := 1
            ) AS RANK ,@V_USER_ID := USER_ID AS G_USER_ID
            FROM
                (
                    SELECT
                        MESSAGE_ID,
                        USER_ID,
                        CREATE_TIME,
                        MESSAGE_CONTEXT,
                        GET_USER_ID,
                        SEND_USER_ID
                    FROM
                        (
                            SELECT
                                MESSAGE_ID,
                                GET_USER_ID,
                                SEND_USER_ID,
                                GET_USER_ID AS USER_ID,
                                CREATE_TIME,
                                MESSAGE_CONTEXT
                            FROM
                                T_SD_MESSAGE
                            WHERE
                                GET_USER_ID != '1234'
                            UNION ALL
                                SELECT
                                    MESSAGE_ID,
                                    GET_USER_ID,
                                    SEND_USER_ID,
                                    SEND_USER_ID AS USER_ID,
                                    CREATE_TIME,
                                    MESSAGE_CONTEXT
                                FROM
                                    T_SD_MESSAGE
                                WHERE
                                    SEND_USER_ID != '1234'
                        ) METADATA
                    ORDER BY
                        USER_ID ASC,
                        CREATE_TIME DESC
                ) SRC,
                (
                    SELECT
                        @V_RANK = 0,
                        @V_USER_ID := NULL
                ) VARS
        ) SRC
    WHERE
        RANK = 1
    ORDER BY
        CREATE_TIME DESC

    一个过程;

    DROP PROCEDURE
    IF EXISTS PROCE_USER_NEW_MSG;
    
    DROP TEMPORARY TABLE
    IF EXISTS TEM_USER_NEW_MSG;
    DELIMITER || 
    
    
    CREATE PROCEDURE PROCE_USER_NEW_MSG (
        IN FRIST_RESULT INT,
        IN FETCH_SIZE INT
    )
    BEGIN
        SELECT
            M.MESSAGE_ID,
            M.GET_USER_ID,
            M.SEND_USER_ID,
            M.MESSAGE_CONTEXT,
            M.CREATE_TIME,
            G_U.USER_NAME AS G_USER_NAME,
            S_U.USER_NAME AS S_USER_NAME,
            G_H.GENERAL_PIC_THUMBNAIL_URL AS G_HEADER,
            S_H.GENERAL_PIC_THUMBNAIL_URL AS S_HEADER
        FROM
            T_SD_MESSAGE M
        LEFT JOIN T_SD_USER G_U ON M.GET_USER_ID = G_U.USER_ID
        LEFT JOIN T_SD_USER S_U ON M.SEND_USER_ID = S_U.USER_ID
        LEFT JOIN T_SD_GENERAL_PICTURE G_H ON G_H.GENERAL_PICTURE_ID = G_U.USER_HEADER_PIC_ID
        LEFT JOIN T_SD_GENERAL_PICTURE S_H ON S_H.GENERAL_PICTURE_ID = S_U.USER_HEADER_PIC_ID
        WHERE
            M.MESSAGE_ID IN (
                SELECT
                    MESSAGE_ID
                FROM
                    (
                        SELECT
                            MESSAGE_ID,
                            RANK,
                            MESSAGE_CONTEXT,
                            CREATE_TIME
                        FROM
                            (
                                SELECT
                                    SRC.*,
                                IF (
                                    @V_USER_ID = USER_ID ,@V_RANK := @V_RANK + 1 ,@V_RANK := 1
                                ) AS RANK ,@V_USER_ID := USER_ID AS G_USER_ID
                                FROM
                                    (
                                        SELECT
                                            MESSAGE_ID,
                                            USER_ID,
                                            CREATE_TIME,
                                            MESSAGE_CONTEXT,
                                            GET_USER_ID,
                                            SEND_USER_ID
                                        FROM
                                            (
                                                SELECT
                                                    MESSAGE_ID,
                                                    GET_USER_ID,
                                                    SEND_USER_ID,
                                                    GET_USER_ID AS USER_ID,
                                                    CREATE_TIME,
                                                    MESSAGE_CONTEXT
                                                FROM
                                                    T_SD_MESSAGE
                                                WHERE
                                                    GET_USER_ID != '3000'
                                                UNION ALL
                                                    SELECT
                                                        MESSAGE_ID,
                                                        GET_USER_ID,
                                                        SEND_USER_ID,
                                                        SEND_USER_ID AS USER_ID,
                                                        CREATE_TIME,
                                                        MESSAGE_CONTEXT
                                                    FROM
                                                        T_SD_MESSAGE
                                                    WHERE
                                                        SEND_USER_ID != '3000'
                                            ) METADATA
                                        ORDER BY
                                            USER_ID ASC,
                                            CREATE_TIME DESC
                                    ) SRC,
                                    (
                                        SELECT
                                            @V_RANK = 0,
                                            @V_USER_ID := NULL
                                    ) VARS
                            ) SRC
                        WHERE
                            RANK = 1
                        ORDER BY
                            CREATE_TIME DESC
                    ) SRC
            )
        ORDER BY
            M.CREATE_TIME DESC
        LIMIT FRIST_RESULT,
        FETCH_SIZE ;
    END|| 
    DELIMITER ;
    
    
    -- LIMIT  FRIST_RESULT ,FETCH_SIZE
    CALL PROCE_USER_NEW_MSG (0, 2);

    转自:  http://ace105.blog.51cto.com/639741/724411

  • 相关阅读:
    根据时间段查询数据并按照降序排列
    Json数组(以[ ] 中括号开头)字符串转为json对象
    Java 后台请求第三方系统接口详解
    Map 集合 和 String 字符串相互转换工具类
    并发工具类——CountDownLatch、CyclicBarrier、Semaphore与Exchanger
    AQS相关
    Atomic原子类
    CAS相关
    synchronized关键字相关
    谈谈对volatile关键字的理解
  • 原文地址:https://www.cnblogs.com/mjorcen/p/4078634.html
Copyright © 2020-2023  润新知