如何在order和group之后选择不同的行?

jslywgbw  于 2021-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(330)

我有一张这样的table:

post    |   date    |   tags
--------+-----------+-------
post3   |   2016    |   bbb
post1   |   2018    |   aaa
post2   |   2017    |   ccc
post1   |   2018    |   bbb
post3   |   2016    |   aaa
post2   |   2017    |   bbb
post2   |   2017    |   bbb
post1   |   2018    |   ccc
post3   |   2016    |   ccc

我想得到以下结果:

post    |   date    |   tags
------- +---------- +--------
post1   |   2018    |   aaa
post2   |   2017    |   bbb
post3   |   2016    |   ccc

换句话说,我要做的是:首先,根据列(在本例中是date列)对表进行排序。其次,根据另一列(在本例中是column标签)进行分组。最后,我希望post专栏的结果不要重复。
第一和第二部分我知道怎么做。我应用下面的查询。。。

SELECT post, `date`, tag
FROM tabela AS t1
WHERE t1.`date` = (
    SELECT MAX(t2.`date`) 
    FROM tabela AS t2 
    WHERE t1.tag = t2.tag
)

... 我得到以下结果:

post    |   data    |   tags
------- +---------- +--------
post1   |   2018    |   aaa
post1   |   2018    |   bbb
post1   |   2018    |   ccc

如您所见,问题是post1对所有标记都是重复的。我不想这样。我希望根据date列给出的最大值智能地填充所有行,但post列中不能重复。
我该怎么做?
ps:对不起,我的英语错了,我不是美国人。

ulydmbyx

ulydmbyx1#

在v8x之前的mysql版本中,可以使用如下变量:

SELECT
      post, `date`, tags
FROM (
    SELECT
          @row_num :=IF(@prev_value=t.tags, @row_num + 1, 1) AS RowNumber
        , t.post
        , t.`date`
        , t.tags
        , @prev_value := t.tags
    FROM mytable t
    CROSS JOIN (SELECT @row_num :=1,  @prev_value :='') vars
    ORDER BY
          t.tags
          , t.`date` DESC
    ) d
WHERE RowNumber = 1
ORDER BY
      tags, `date`
;

+----+-------+------+------+
|    | post  | date | tags |
+----+-------+------+------+
|  1 | post1 | 2018 | aaa  |
|  2 | post1 | 2018 | bbb  |
|  3 | post1 | 2018 | ccc  |
+----+-------+------+------+

请参见:http://rextester.com/hxq91572
对于较新版本的mysql或mariadb等变体,您只需使用 row_number() over() 这样地:

SELECT
      post, `date`, tags
FROM (
    SELECT
          t.post
        , t.`date`
        , t.tags
        , row_number() over(partition by t.tags order by t.`date`DESC) as RowNumber
    FROM table1 t
    ) d
WHERE RowNumber = 1
ORDER BY
      tags, `date`
;

在上述两种查询变体中,您都是基于数据的顺序为每个“第一行”计算1的值。一旦知道需要的行引用,就可以过滤掉任何不需要的行。

相关问题