2009-08-19 32 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。定義視圖的方式是,所有與人員/狀態表中的給定pubid(主鍵)匹配的列(都具有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

我最終什麼事是使用陣列列在我看來,這樣做(在這案例articles_view)做我所有的排序。這樣我就可以在主要查詢中的「列」上完成所有工作,完全避免使用JOINS。定義視圖的方式是,所有與人員/狀態表中的給定pubid(主鍵)匹配的列(都具有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

呃這就是我害怕的,我真的想避免使用連接(產品會變得太大,因此使用子查詢來代替)。 – 2009-08-19 23:23:08

+0

使用內部聯接您只會得到合適的結果,並且查詢優化器應該確定一個計劃,在應用聯接之前刪除不滿足where子句的任何內容。 – 2009-08-19 23:30:25

1

你只是排序所使用的陳述中的數據。您需要對頂級Select語句進行排序。

編輯:

而且,由於IN子句內的SELECT語句無助於你的結果的總體排序,你應該從他們的條款刪除訂單,從而防止服務器不必做不必要的處理。

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

因爲我不知道用戶是否想要在人員或狀態表中的字段上進行排序,所以我將不得不加入。問題在於我留下的產品,只需要將這麼多數據納入查詢中,但聽起來像這是我唯一的選擇,如果我想允許各種排序選項。 – 2009-08-19 23:32:11

+1

無論您是否加入JOIN,您都將這麼多數據納入查詢*處理。如果你的擔心是簡單地返回那麼多*列*,那麼*很容易*糾正:只需要'SELECT articles_view。*'而不是'SELECT *' – VoteyDisciple 2009-08-19 23:51:50