Подзапросы и сортировка? (СОРТИРОВАТЬ ПО) - PullRequest
2 голосов
/ 20 августа 2009

Так что мой синтаксис, по-видимому, правильный во всех трех случаях (PostgreSQL ни о чем не беспокоится), но результаты возвращаются в том же порядке со всеми тремя этими запросами. Даже более странно, когда я добавляю / удаляю DESC из любого из следующего, это также не оказывает никакого влияния. Можно ли сортировать результаты по элементам подзапроса или нет?

Sort by affiliation
SELECT * FROM articles_view WHERE (1=1) 
AND spubid IN 
  (SELECT people.spubid FROM people WHERE (people.slast ilike 'doe') 
    GROUP BY people.spubid, people.slast, people.saffil) 
AND spubid IN 
  (SELECT status.spubid FROM status WHERE ((status.imonth >= 01 OR status.imonth IS NULL) AND status.iyear >= 2000) AND ((status.imonth <= 01 OR status.imonth IS NULL) AND status.iyear <= 2008) ORDER BY status.iyear, status.imonth)

Sort by last name, descending order
SELECT * FROM articles_view WHERE (1=1) 
AND spubid IN 
  (SELECT people.spubid FROM people WHERE (people.slast ilike 'doe') 
    GROUP BY people.spubid, people.slast, people.saffil ORDER BY people.slast DESC) 
AND spubid IN 
  (SELECT status.spubid FROM status WHERE ((status.imonth >= 01 OR status.imonth IS NULL) AND status.iyear >= 2000) AND ((status.imonth <= 01 OR status.imonth IS NULL) AND status.iyear <= 2008))

Sort by year/month descending order
SELECT * FROM articles_view WHERE (1=1) 
AND spubid IN 
  (SELECT people.spubid FROM people WHERE (people.slast ilike 'doe') 
    GROUP BY people.spubid, people.slast, people.saffil ) 
AND spubid IN 
  (SELECT status.spubid FROM status WHERE ((status.imonth >= 01 OR status.imonth IS NULL) AND status.iyear >= 2000) AND ((status.imonth <= 01 OR status.imonth IS NULL) AND status.iyear <= 2008) ORDER BY status.iyear, status.imonth DESC)

Я просто не уверен, почему условия ORDER BY не влияют на порядок результатов.

********* ОБНОВЛЕНИЕ:

В итоге я использовал столбец массива в моем представлении (в данном случае article_view), чтобы выполнить всю мою сортировку. Таким образом, я делаю все свои сортировки по «столбцу» в основном запросе и полностью избегаю использования JOINS. Как определяется представление, все столбцы, соответствующие заданному pubid (первичному ключу) в таблице people / status (оба имеют 1-> many), сохраняются в столбцах массива в представлении. Мой запрос с сортировкой выглядит так:

SELECT * FROM articles_view WHERE 
  ((articles_view.skeywords_auto ilike '%ice%') OR (articles_view.skeywords_manual ilike '%ice%')) 
  ORDER BY (articles_view.authors[1]).slast

Причина, по которой это работает, заключается в том, что я всегда знаю, что первый член массива (в Postgres первый индекс равен 1, а не обычному 0), это основной автор (или основной статус), который мне нужен для сортировки. .

Ответы [ 4 ]

3 голосов
/ 20 августа 2009

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

Что-то вроде:

SELECT * 
FROM articles_view
       INNER JOIN status ON articles_view.spubid = status.spubid
       INNER JOIN people ON articles_view.spubid = people.spubid
WHERE ((status.imonth >= 01 OR status.imonth IS NULL) AND status.iyear >= 2000)
       AND ((status.imonth <= 01 OR status.imonth IS NULL)
       AND status.iyear <= 2008 AND people.slast ilike 'doe')
ORDER BY status.iyear, status.imonth
2 голосов
/ 20 августа 2009

Вы не заказываете запрос external ; вы только заказываете внутренний запрос. Это совершенно законно, но все, что вы делаете с этими внутренними результатами, сравнивает spubid с ними, и неважно, в каком порядке вы это делаете.

То, что вы ищете, это JOIN.

SELECT * 
FROM articles_view
INNER JOIN status ON (status.spubid = articles_view.spubid AND ((status.imonth >= 01 OR status.imonth IS NULL) AND status.iyear >= 2000) AND ((status.imonth <= 01 OR status.imonth IS NULL) AND status.iyear <= 2008))
WHERE spubid IN 
  (SELECT people.spubid FROM people WHERE (people.slast ilike 'doe') 
   GROUP BY people.spubid, people.slast, people.saffil ) 
ORDER BY status.iyear, status.imonth DESC

(Вы также можете переписать другой поиск как объединение, но для простоты я оставил его в покое.)

1 голос
/ 20 августа 2009

Вы сортируете только те данные, которые используются операторами IN. Вам нужно отсортировать ваш оператор Select верхнего уровня.

Edit:

И поскольку операторы Select внутри предложений IN не способствуют общей сортировке ваших результатов, вы должны удалить из них заказы по предложениям, тем самым предотвращая ненужную обработку сервером.

0 голосов
/ 27 августа 2009

В итоге я использовал столбец массива в моем представлении (в данном случае article_view), чтобы выполнить всю мою сортировку. Таким образом, я делаю все свои сортировки по «столбцу» в основном запросе и полностью избегаю использования JOINS. Как определено представление, все столбцы, соответствующие заданному pubid (первичному ключу) в таблице people / status (оба имеют 1-> many), сохраняются в столбцах массива в представлении. Мой запрос с сортировкой выглядит так:

SELECT * FROM articles_view WHERE 
  ((articles_view.skeywords_auto ilike '%ice%') OR (articles_view.skeywords_manual ilike '%ice%')) 
  ORDER BY (articles_view.authors[1]).slast

Причина, по которой это работает, в том, что я всегда знаю, что первый член массива (в Postgres первый индекс равен 1, а не обычному 0), это основной автор (или основной статус), который мне нужен для сортировки .

...