2

したがって、私の構文は 3 つのケースすべてで明らかに正しいですが (PostgreSQL は何も不満を抱いていません)、結果はこれら 3 つのクエリすべてで同じ順序で返されます。次のいずれかに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 を使用する必要が完全に回避されます。ビューが定義される方法では、people/status テーブルの特定の pubid (主キー) に一致するすべての列 (どちらも 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 では、最初のインデックスは通常の 0 ではなく 1 です) が、ソートに必要な主要な作成者 (または主要なステータス) であることを常に知っているためです。

4

4 に答える 4

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
于 2009-08-19T23:20:20.180 に答える
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

(他のルックアップを結合として書き直すこともできますが、簡単にするために、それはそのままにしました。)

于 2009-08-19T23:22:58.490 に答える
1

IN ステートメントで使用されるデータのみを並べ替えます。トップレベルの Select ステートメントをソートする必要があります。

編集:

また、IN 句内の Select ステートメントは結果の全体的な並べ替えに寄与していないため、それらから order by 句を削除して、サーバーが不要な処理を実行するのを防ぐ必要があります。

于 2009-08-19T23:22:26.447 に答える
0

私が最終的に行ったことは、ビュー (この場合は article_view) で配列列を使用してすべての並べ替えを行うことでした。そうすれば、プライマリクエリの「列」ですべての並べ替えを行い、JOINS を使用する必要が完全に回避されます。ビューが定義される方法では、people/status テーブルの特定の pubid (主キー) に一致するすべての列 (どちらも 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 では、最初のインデックスは通常の 0 ではなく 1 です) が、ソートに必要な主要な作成者 (または主要なステータス) であることを常に知っているためです。

于 2009-08-27T16:38:03.327 に答える