MySQL - Как выбрать отдельные строки после заказа и группы? - PullRequest
0 голосов
/ 14 сентября 2018

У меня есть такая таблица:

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

Другими словами, я хочу сделать следующее: во-первых, упорядочить таблицу на основе столбца (который в данном случае является столбцом даты). И, во-вторых, группировать по другому столбцу (который в данном случае является тегом столбца). И я хочу, наконец, чтобы результат колонки записей не повторялся.

Первую и вторую часть я умею делать. Я применяю запрос ниже ...

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 повторяется для всех тегов. И я не хочу, чтобы это произошло. Я хочу, чтобы все строки были заполнены разумно на основе наибольшего значения, указанного в столбце даты, но без повторения в столбце записи.

Как я могу это сделать?

PS: извините за английские ошибки, я не американец.

1 Ответ

0 голосов
/ 14 сентября 2018

В версиях MySQL до v8x вы можете использовать переменные следующим образом:

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 для каждой «первой строки» на основе упорядочения данных.Как только требуемая ссылка на строку станет известной, вы сможете отфильтровать все нежелательные строки.

...