繁体   English   中英

SQL:根据其他重复值选择精确的最大重复值

[英]SQL: select exact max for repeating value that based on other repeating value

Table with repeating data in each column
|  userid   |   code   |    date    |
|3          |  YYYYYY  | 2017-09-20 |
|3          |  YYYYYY  | 2017-09-21 |
|3          |  YYYYYY  | 2017-09-22 |
|1          |  XXXXXX  | 2017-09-22 |
|1          |  XXXXXX  | 2017-09-23 |
|3          |  XXXXXX  | 2017-09-23 |
|3          |  XXXXXX  | 2017-09-23 |
|2          |  ZZZZZZ  | 2017-09-23 |
|3          |  ZZZZZZ  | 2017-09-23 |
|1          |  ZZZZZZ  | 2017-09-24 |

我需要为每个“代码”获取MAX(date),并为该MAX(date)和“ code”获取“ userid”,并按“ code”进行分组。

SELECT
t1.userid,
t1.code,
t1.date
FROM codes AS t1

INNER JOIN (
            SELECT 
              userid,
              code,
              MAX(date) as maxdate
            FROM codes
            GROUP BY code
            ) AS t2
ON (t1.code = t2.code AND t1.date = t2.maxdate)
ORDER BY date

但是,MAX(date)值应基于userid。

如果代码具有用户1和2和3,则最大日期应基于用户3的代码。

如果代码具有用户2和3,则最大日期应基于用户3的代码。

如果代码具有用户1和2,则最大日期应基于用户2的代码。

如果代码具有用户3,则最长日期应基于用户3的代码。

如果代码具有用户2,则最长日期应基于用户2的代码。

如果代码具有用户1,则最长日期应基于用户1的代码。

响应应包含:基于'userid'值的代码,用户ID和MAX(日期),且gpoup由'code'(每个代码一行)

如何添加此选择? 感谢您的帮助) SQL小提琴

使用ANSI标准的窗口函数:

select c.*
from (select c.*,
             row_number() over (partition by code
                                order by date desc, userid desc
                               ) as seqnum
      from c
     ) c
where seqnum = 1;

您的SQL Fiddle使用不支持窗口功能的MySQL。 在该数据库中,您可以执行以下操作:

SELECT c.*
FROM codes c
WHERE (c.userid, c.date) = (SELECT c2.userid, c2.date
                            FROM codes c2
                            WHERE c2.code = c.code 
                            ORDER BY c2.date DESC, c2.userid DESC
                            LIMIT 1
                           );

这是SQL Fiddle

请注意,由于'XXXXXX'的最大值在数据中多次出现,因此您仍然会重复。

SELECT 
    t1.userid,
    t1.code,
    t1.date
    -- SOME OTHER ROWS FROM TABLE
    FROM 
      codes AS t1 
      -- JOIN TABLE WITH SEARСH ROWS
      INNER JOIN (
        -- BEGIN SELECT MAX LOGIC
        SELECT 
          code, 
          CASE WHEN max3date IS NOT NULL THEN max3date WHEN max2date IS NOT NULL THEN max2date ELSE max1date END AS maxdate
        FROM 
          (
            -- BEGIN SELECT MAX FOR EACH GROUP
            SELECT 
              all1.code, 
              u3.max3date, 
              u2.max2date, 
              u1.max1date 
            FROM 
              codes AS all1 
              LEFT JOIN (
                SELECT 
                  code,  
                  MAX(date) AS max3date 
                FROM 
                  codes 
                WHERE userid LIKE '3%' 
                GROUP BY 
                  code
              ) AS u3 ON (all1.code = u3.code)
              LEFT JOIN (
                SELECT 
                  code, 
                  MAX(date) AS max2date 
                FROM 
                  codes 
                WHERE userid LIKE '2%'
                GROUP BY 
                  code
              ) AS u2 ON (all1.code = u2.code) 
              LEFT JOIN (
                SELECT 
                  code,  
                  MAX(date) AS max1date  
                FROM 
                  codes 
                WHERE userid LIKE '1%' 
                GROUP BY 
                  code
              ) AS u1 ON (all1.code = u1.code) 
            GROUP BY 
              code
          ) t3
      ) AS t2 ON (
        t1.code = t2.code 
        AND t1.date = t2.maxdate
      )  
    ORDER BY 
      t1.date

它对我有2400万行有效。 日期(时间)应该是唯一的。 SQL小提琴

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM