Найти первую запись нескольких значений в одном запросе - PullRequest
1 голос
/ 02 марта 2020

Таблица

            timestamp             | tracker_id | position 
----------------------------------+------------+----------
 2020-02-01 21:53:45.571429+05:30 |         15 |        1
 2020-02-01 21:53:45.857143+05:30 |         11 |        1
 2020-02-01 21:53:46.428571+05:30 |         15 |        1
 2020-02-01 21:53:46.714286+05:30 |         11 |        2
 2020-02-01 21:53:54.714288+05:30 |         15 |        2
 2020-02-01 21:53:55+05:30        |         12 |        1
 2020-02-01 21:53:55.285714+05:30 |         11 |        1
 2020-02-01 21:53:55.571429+05:30 |         15 |        3
 2020-02-01 21:53:55.857143+05:30 |         13 |        1
 2020-02-01 21:53:56.428571+05:30 |         11 |        1
 2020-02-01 21:53:56.714286+05:30 |         15 |        1
 2020-02-01 21:53:57+05:30        |         13 |        2
 2020-02-01 21:53:58.142857+05:30 |         12 |        2
 2020-02-01 21:53:58.428571+05:30 |         20 |        1

Вывод

           timestamp             | tracker_id | position 
----------------------------------+------------+----------
2020-02-01 21:53:45.571429+05:30 |         15 |        1
2020-02-01 21:53:45.857143+05:30 |         11 |        1
2020-02-01 21:53:55+05:30        |         12 |        1

Как найти первую запись WHERE tracker_id IN ('15', '11', '12') в одном запросе?

Я могу найти первую запись, запрашивая отдельно для каждого tracker_id:

SELECT *
FROM my_table
WHERE tracker_id = '15'
ORDER BY timestamp
LIMIT 1;

Ответы [ 6 ]

2 голосов
/ 02 марта 2020

В Postgres это можно сделать с помощью предложения DISTINCT ON ():

select distinct on (tracker_id) *
from the_table
where tracker_id in (11,12,15)
order by tracker_id, "timestamp" desc;

Онлайн пример

1 голос
/ 02 марта 2020

Если вы хотите, чтобы первая строка соответствовала каждому из ваших IN значений, вы можете использовать оконную функцию:

SELECT src.timestamp, src.tracker_id, src.position
FROM (
  SELECT 
    t.timestamp, t.tracker_id, t.position, 
    ROW_NUMBER() OVER(PARTITION BY tracker_id ORDER BY timestamp DESC) myrownum
  FROM mytable t
  WHERE tracker_id IN ('15', '11', '12')
) src
WHERE myrownum = 1 -- Get first row for each "tracker_id" grouping

Это вернет первую строку, которая соответствует каждому из ваших IN значения, упорядоченные по timestamp.

1 голос
/ 02 марта 2020
select distinct on (tracker_id) *
from the_table
where tracker_id in ( select distinct tracker_id from the_table)
order by tracker_id, "timestamp" desc;
1 голос
/ 02 марта 2020

Найти этот запрос:

Вы можете раскомментировать условие where, если хотите выполнить запрос для выбранного tracker_id

   ;WITH CTE AS
   (
      SELECT ROW_NUMBER() OVER (PARTITION BY tracker_id ORDER BY timestamp) 
      duplicates, * FROM my_table -- WHERE tracker_id IN (15,11,12)
   )
   SELECT timestamp, tracker_id, position FROM CTE WHERE duplicates = 1
1 голос
/ 02 марта 2020

Я назвал ваш столбец timestampl col1, потому что я не рекомендую называть ваши столбцы ключевыми словами.

select * from mytable m
where m.col1 = (select min(col1)
              from mytable m1
              where m.tracker_id = m1.tracker_id
              group by tracker_id)
and m.tracker_id in (11,15,12);

Вот небольшая демонстрация

1 голос
/ 02 марта 2020

Вы можете использовать first_value с вложенным запросом select:

select mt.*
from my_table mt
where mt.timestamp in (
    select first_value(imt.timestamp) over (partition by imt.tracker_id order by imt.timestamp)
    from my_table imt
    where imt.tracker_id in ('11', '12', '15')
)

Я предполагаю, что timestamp уникально, как вы сказали в комментарии. Вы всегда можете заменить объединяющий столбец первичным ключом, например id.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...