2013-12-18 4 views
-1

У меня есть запрос, как это:SELECT DISTINCT ON из подзапроса

SELECT user_set, read, last_updated, user_id, pk_id 
FROM interaction_log 
WHERE user_id = 2002 
ORDER BY read, last_updated, user_set 

база данных используется в PostgreSQL (9.1) и требование что-то вроде этого:

  • Упорядочение столбцы могут не меняться (упорядочивать по состоянию чтения, затем по последнему обновлению, а затем по user_set)
  • Столбец «чтение» представляет собой целое число, которое может принимать значение только «1» или «0». last_updated - положительное целое число, а user_set - строка.
  • Столбец user_set должен быть уникальным. например: если есть 3 записей для user_set под названием 'дэвы', как показано ниже:

    1. user_set = "УБС", прочитать = 1, LAST_UPDATED = 10, user_id = 2002, pk_id = 1
    2. user_set = " Devs», чтение = 0, LAST_UPDATED = 30, идентификатор_пользователь = 2002, pk_id = 3
    3. user_set = "дэвы" читать = 0, LAST_UPDATED = 20, идентификатор_пользователь = 2002, pk_id = 2

Тогда вторая запись (с pk_id = 3) должна появиться наверху, и никто другой не должен появляться b потому что это было «read = 0», а затем последнее значение было 30 (выше 20).

SELECT DISTINCT ON (user_set) хочет, чтобы у меня был user_set в качестве первого порядка сортировки, который изменил бы порядок, и, следовательно, я не могу этого сделать.

Если я что-то вроде этого:

SELECT DISTINCT ON (user_set) user_set, read, last_updated, thread_id, user_id, id 
FROM message_interaction_log 
    WHERE (user_set, read, last_updated, thread_id, user_id, id) IN 
     (SELECT user_set, read, last_updated, thread_id, user_id, id 
      FROM message_interaction_log 
      WHERE user_id = 14 
      ORDER BY read DESC, last_updated, user_set) 

Тогда 'заказ по эффекту на «читать» невидим и делает «читать ASC» и «читать DESC» остается тем же самым.

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

+0

В чем заключалось такое требование? –

+3

Я думаю, что ваш пост усечен. – MillaresRoo

+0

Переименуйте столбец 'read'. Не используйте ** [зарезервированные ключевые слова] (http://www.postgresql.org/docs/8.1/static/sql-keywords-appendix.html) ** в качестве имен столбцов. –

ответ

0

Вам необходимо использовать PARTITION BY с функцией OLAP;

SELECT user_set, read, last_updated, user_id, pk_id 
FROM (SELECT user_set, read, last_updated, user_id, pk_id, 
      ROW_NUMBER() OVER(PARTITION BY user_set 
           ORDER BY read ASC, last_updated DESC) as rn 
     FROM interaction_log 
     WHERE user_id = 2002) data 
WHERE rn = 1 
ORDER BY read ASC, last_updated DESC, user_set ASC 

По существу, это находит «верхнюю» строку для каждой группы (user_set), и выбрасывает все остальное. Для достижения наилучших результатов вам, вероятно, нужен индекс (read ASC, last_updated DESC, user_set (в любом направлении))

+0

Спасибо большое :) Это работает так, как это было необходимо. –

Смежные вопросы