サブクエリに正確に1つの異なる結果と指定された値があるかどうかを簡潔に確認するにはどうすればよいですか?


10

私は次のように書いていることに気づきました:

select 'yes' 
where exists(select * from foo where val=1)
and not exists(select * from foo where val<>1);

読みやすさを犠牲にせずにもっと簡潔な方法があるかどうか疑問に思っています。

回答として投稿している方法を1つ見つけましたが、完全に満足しているわけではなく、代替案に非常に興味があります。

この場合valは一意ですfoo-重複はありません


サブクエリの結果に正確に1行が必要であることを正しく理解していますか?
Erwin Brandstetter 2012


タイトルで言及したもの。それが「明確」の後か前の1つの結果であるべきかどうか、私にはわかりませんでした。
Erwin Brandstetter 2012

はいああ、1 :)私はむしろ紛らわしい私の中のサブクエリに言及していたことを答え -あなたはあなたにも使用することができ、たとえば、はるかに具体的かつ柔軟であるcount(distinct val)私の現実世界のケースでは、それは違いはありませんが、
ジャックは、try語りますtopanswers.xyz

回答:


8

簡潔、高速(特に多くの行がある場合)、可読性に関する私のお気に入りであり、dupesでも機能します。

SELECT count(*) = 1 AND min(val) = 1 FROM foo;

戻り値TRUE/ FALSE..またはNULL- だけで1行だけの場合はval IS NULL、理由はcount()決して戻っNULLあるいは全く行。

この1例では、例の2番目は、最初の例と同じです。


質問のクエリはNULL値で失敗します。簡単なデモを考えてみましょう:

CREATE TABLE foo (id int, val int);
INSERT INTO foo VALUES (1, 1),(2, NULL);

SELECT 'yes' 
WHERE      EXISTS(SELECT * FROM foo WHERE val =  1)
AND    NOT EXISTS(SELECT * FROM foo WHERE val <> 1);

IS DISTINCT FROMこれを修正しますが、それでも重複が発生して失敗する可能性がvalあります-この場合は除外しました。


あなたの答えはうまくいきます。
戻り値'yes'/行なし。

ただし、この短い形式が望ましいです。PostgreSQL(Oracleとは異なり)には適切なbooleanがあることを忘れないでください。

SELECT array_agg(val) = array[1] FROM foo;

TRUE/ FALSE/を返しますNULL


すばらしい、ありがとう、もっと良い方法があることを知っていました:)
ジャックはtopanswers.xyzを

5

@アーウィンの答えのバリエーション。ノーCOUNT()すべてで、唯一MIN()MAX()。大きなテーブルと(あなたのケースではなく)複製する方が少し効率的かもしれませんval

SELECT MIN(val) = 1 AND MAX(val) = 1 FROM foo;

+1ありがとうございます。もちろん、nullと重複の処理は異なります(ある場合)
ジャックはtopanswers.xyzを

@ジャック:はい。テーブルにnullがありますか?または、両方の場合(あり、なし)の回答が必要ですか?
ypercubeᵀᴹ

いいえ鉱山はありません-私はどちらかを使用することができます:)
ジャックはtopanswers.xyz試し言う

だろうくらいのマッチング・インデックスを持つ大きなテーブルの上に速いが、全く同じようなインデックスが存在しない場合に実行する-クエリ結果をテストするときのように。
Erwin Brandstetter 2012


1

これはtruefalseまたは空の結果を返します。

 select j.val is null 
 from foo left join foo as j on j.val <> foo.val 
 where foo.val = 1 limit 1;

一見すると、どこにfalse値がある場合、これは返らないようです?fooval<>1
ジャックはtopanswers.xyzを

@JackDouglasおお、ごめんなさい。初めて間違った仕事を理解しました。修繕。
grayhemp

機能NULLします- この場合は除外されていないas値を除きます。
Erwin Brandstetter 2012

@ErwinBrandstetter NULLは使用するIS [NOT] DISTINCT FROMと思います。
grayhemp

1
@grayhemp:この場合はありません。LEFT JOIN foo j ON j.val <> foo.valで行を検出できませんj.val IS NULL。一緒に含める場合はON j.val IS DISTINCT FROM foo.valj定義済みの別の列をチェックしNOT NULLて、2つのケースを区別する必要があります。ただし、追加の列は定義されていません。
Erwin Brandstetter 2012
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.