порядок по строкам, которые существуют в другой таблице - PullRequest
0 голосов
/ 28 декабря 2018

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

Одна называется message_log, а другая - assigned_conversation.

assigned_conversation также содержит столбец match_id

У меня есть запрос ниже, который работает без проблем.

SELECT m.* 
FROM   message_log m 
WHERE  m.from_id <> 'MYID' 
       AND m.to_id = 'MYID' 
       AND m.unix_timestamp = (SELECT Max(unix_timestamp) 
                               FROM   message_log 
                               WHERE  match_id = m.match_id 
                               GROUP  BY match_id) 

Единственное, что я хочу изменить дляПриведенный выше запрос состоит в том, как сортируются результаты.

Можно ли отсортировать результаты таким образом, чтобы для match_id s, существующего в таблице assigned_conversation, располагаться поверх результатова для match_id s, которых нет в таблице assigned_conversation, отсортировать после тех, которые существуют в таблице assigned_conversation?

Ответы [ 3 ]

0 голосов
/ 28 декабря 2018

Вместо того, чтобы выполнять подзапрос, вы можете просто использовать отдельный, чтобы удостовериться, что вы получаете только самую новую запись в журнале, а затем, оставив присоединение к параметру assign_conversation и упорядочив по первому match_id, равно null, а затем m.unix_timestamp desc, вы должны получить ожидаемый результат вчистый и эффективный способ

SELECT DISTINCT m.* 
FROM   message_log m 
left join assigned_conversation ac on ac.match_id = m.match_id
WHERE  m.from_id <> 'MYID' 
       AND m.to_id = 'MYID' 
ORDER BY ac.match_id is null, m.unix_timestamp desc
0 голосов
/ 28 декабря 2018

Я бы упростил запрос до:

SELECT DISTINCT ON (ml.match_id) ml.* 
FROM message_log ml 
WHERE ml.from_id <> 'MYID' AND
      ml.to_id = 'MYID' 
ORDER BY ml.match_id, ml.unix_timestamp DESC;

Затем вы можете использовать его как подзапрос, чтобы получить желаемый конечный заказ:

SELECT ml.*
FROM (SELECT DISTINCT ON (ml.match_id) ml.*
      FROM message_log ml 
      WHERE ml.from_id <> 'MYID' AND
            ml.to_id = 'MYID' 
      ORDER BY ml.match_id, ml.unix_timestamp DESC
     ) ml
ORDER BY (EXISTS (SELECT 1 FROM assigned_conversation ac WHERE ac.match_id = ml.match_id))::int DESC,
         match_id;

Однако я был бы склоненчтобы добавить флаг к данным в наборе результатов:

SELECT ml.*
FROM (SELECT DISTINCT ON (ml.match_id) ml.*,
             (EXISTS (SELECT 1 FROM assigned_conversation ac WHERE ac.match_id = ml.match_id))::int as ac_flag
      FROM message_log ml 
      WHERE ml.from_id <> 'MYID' AND
            ml.to_id = 'MYID' 
      ORDER BY ml.match_id, ml.unix_timestamp DESC
     ) ml
ORDER BY ac_flag desc, match_id;
0 голосов
/ 28 декабря 2018

Одним из вариантов будет заказ с использованием выражения CASE, которое проверяет, можно ли найти данную match_id во внешнем запросе в таблице assigned_conversation.

SELECT m.* 
FROM   message_log m
WHERE  m.from_id <> 'MYID' 
   AND m.to_id = 'MYID' 
   AND m.unix_timestamp = (SELECT Max(unix_timestamp) 
                           FROM   message_log 
                           WHERE  match_id = m.match_id 
                           GROUP  BY match_id)
ORDER BY
    CASE WHEN EXISTS (SELECT 1 FROM assigned_conversation a
                      WHERE a.match_id = m.match_id)
         THEN 0 ELSE 1 END;

Обратите внимание, что мы могли быпытался присоединиться слева к assigned_conversation, но это могло привести к появлению дубликатов в вашем наборе результатов, предполагая, что match_id во внешнем запросе может появляться более одного раза в assigned_conversation.Использование EXISTS решает эту проблему.

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