Подтвердить что ты не робот

Выберите 3 последних записей, в которых значения одного столбца отличаются

У меня есть следующая таблица:

    id       time      text      otheridentifier
    -------------------------------------------
    1        6         apple     4
    2        7         orange    4
    3        8         banana    3
    4        9         pear      3
    5        10        grape     2

Что я хочу сделать, это выбрать 3 последних записи (по времени), чей otheridentifier отличается. Таким образом, в этом случае результат будет id s: 5, 4 и 2.

id= 3 будет пропущен, потому что есть более поздняя запись с тем же полем otheridentifier.

Вот что я пытался сделать:

SELECT * FROM `table` GROUP BY (`otheridentifier`) ORDER BY `time` DESC LIMIT 3

Однако в итоге я получаю строки id= 5, 3 и 1 вместо 5, 4, 2, как и ожидалось.

Может кто-нибудь сказать мне, почему этот запрос не вернет то, что я ожидал? Я попытался изменить ORDER BY на ASC, но это просто переставляет возвращенные строки в 1, 3, 5.

4b9b3361

Ответ 1

Он не возвращает то, что вы ожидаете, потому что группировка происходит до упорядочения, что отражается в позиции предложений в инструкции SQL. Вам, к сожалению, придется полюбить вас, чтобы получить нужные вам строки. Попробуйте следующее:

SELECT *
FROM `table`
WHERE `id` = (
    SELECT `id`
    FROM `table` as `alt`
    WHERE `alt`.`otheridentifier` = `table`.`otheridentifier`
    ORDER BY `time` DESC
    LIMIT 1
)
ORDER BY `time` DESC
LIMIT 3

Ответ 2

Вы можете присоединиться к таблице непосредственно для фильтрации последней записи на otheridentifier, а затем взять верхние 3 строки этого:

SELECT last.*
FROM `table` last
LEFT JOIN `table` prev 
    ON prev.`otheridentifier` = last.`otheridentifier`
    AND prev.`time` < last.`time`
WHERE prev.`id` is null
ORDER BY last.`time` DESC 
LIMIT 3

Ответ 3

У меня было аналогичное требование, но у меня были более продвинутые критерии выбора. Используя некоторые из других ответов, я не смог получить именно то, что мне было нужно, но я обнаружил, что вы все еще можете делать GROUP BY после и ORDER BY следующим образом:

SELECT t.* FROM (SELECT * FROM table ORDER BY time DESC) t 
GROUP BY t.otheridentifier

Ответ 4

SELECT * FROM table t1 
WHERE t1.time = 
    (SELECT MAX(time) FROM table t2 
     WHERE t2.otheridentifier = t1.otheridentifier)

Ответ 5

Андомарский ответ, вероятно, лучше всего в том, что он не использует подзапрос.

Альтернативный подход:

select *
from   `table` t1
where  t1.`time` in (
                    select   max(s2.`time`)
                    from     `table` t2
                    group by t2.otheridentifier
                    )

Ответ 6

Вы можете использовать этот запрос, чтобы получить правильный ответ:

SELECT * FROM 
      (SELECT * FROM `table` order by time DESC)
          t group by otheridentifier

Ответ 7

как насчет

SELECT *, max(time) FROM `table`  group by otheridentifier

Ответ 8

Это также:

SELECT * FROM
OrigTable T INNER JOIN 
( 
SELECT otheridentifier,max(time) AS duration
FROM T
GROUP BY otheridentifier) S
ON S.duration = T.time AND S.otheridentifier = T.otheridentifier.