2016-08-08 13 views
1

私は自分のjava/hibernateアプリケーションのビューを提供するためにいくつかの列で結合する2つのテーブルを持っています。これは次のようになります。VIEWSでDISTINCTを正しく使用する方法

CREATE VIEW customer_contacts AS cc 
SELECT DISTINCT ON (cust.id) cust.id 
    cust.company 
    cust.zip 
    ... 
    con.name 
    con.forename 
    ... 
FROM contacts con 
LEFT JOIN customer cust ON con.customer = cust.id 
ORDER BY cust.id 

これまでのところとても良いです。非常に簡単です。私のようなビューのSELECT作る場合 は:

SELECT * 
FROM cc 
WHERE name ilike '%schult%' 

私は13結果を取得します。

私は75の結果を得た

SELECT DISTINCT ON (cust.id) cust.id 
    cust.company 
    cust.zip 
    ... 
    con.name 
    con.forename 
    ... 
FROM contacts con 
LEFT JOIN customer cust ON con.customer = cust.id 
WHERE name ilike '%schult%' 
ORDER BY cust.id 

viewステートメントで直接、同じクエリを作る場合は! 私はそれが結果を壊すDISTINCTだと分かりました。しかし、なぜ?

どうすれば正しく使用できますか?

+3

あなたが実行している "同じクエリ" の正確なSQLテキストを表示してください。 –

+0

こんにちはピーター、私は私の質問を明確にし、私は直接の声明を書いた。 – M46

+0

しかし、2番目のクエリで 'WHERE name ilike '%schult%''という条件を忘れた... –

答えて

1

あなたのクエリは、(ビューをベースと直接)適用条件の異なる順序があります。%shult%ため

  • 直接クエリ検索をして、distinct on
  • ビューがdistinct on適用適用され、その後、%shult%
を検索します

distinct onの仕組みをご存知ですか? 与えられた属性に対して最初の行を選択します(適切なソートが定義されていない場合は未定義である可能性があります)。例えば

我々はid=1と、接続された2つの接点name='Schultz'と1とname='Schmidt'と1を顧客に持っているとしましょう。 ビューベースの選択でdistinct onが適用され、連絡先が1つ(この場合は未確定)の顧客を選択するとname ilike '%schult%'が適用されます。シュルツがdistinct onで削除されることがあります。


推奨読書:

https://www.postgresql.org/docs/9.0/static/sql-select.html#SQL-DISTINCT

+0

ありがとう。あなたの最初の点は明確で、私はポストグラムの文書でそれを見つけました。 2番目はない。しかし、私の質問は残っています。私は、私が望むことのない結果をどうやって得るのか?私はHibernateを使用しており、クエリを使用したくありません。だからこそ私はビューを使いたいと思っています。 – M46

+0

そして、ところで。重複がないため、この非常に特殊なケースの結果は同じになります。したがって、順序は重要ではありません。他のクエリでも可能です。 – M46

+0

私はそれを得ることはありません: "重複はありません"。重複がない場合、両方の照会が同じデータを戻します。 –

関連する問題