2009-08-19 3 views
2

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

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 не влияют на порядок результатов.

********* UPDATE:

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

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), является основным автор (или первичный статус), который мне нужен для сортировки.

ответ

0

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

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), является основным автор (или первичный статус), который мне нужен для сортировки.

3

Все вспомогательные запросы делают это набор результатов для условия проверки существования spubid. Вам нужно фактически присоединиться к таблице состояния, а затем использовать столбцы в предложении order by во внешнем запросе.

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

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 
+0

Это то, чего я боялся, я действительно хочу избежать использования соединения (продукт будет слишком большим, следовательно, вместо него будут использоваться вспомогательные запросы). –

+0

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

1

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

Edit:

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

2

Вы не заказываете внешний запрос; вы заказываете только запрос. Это совершенно законно, но все, что вы делаете с этими внутренними результатами, сравнивает 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 

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

+0

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

+1

Вы включаете столько данных в обработку запроса *, являетесь ли вы 'JOIN' или нет. Если ваша проблема просто возвращает много * столбцов *, это * легко * исправлено: просто сделайте 'SELECT articles_view. *' Вместо 'SELECT *' – VoteyDisciple