私はこのエラーを受け取ります:
次のクエリを実行しようとすると発生します。
with expensive_service as (
select s1.*
from service s1, service s2
where s1.price > s2.price
)
select *
from service except expensive_service;
私は実装しようとしていました WITH ... AS
(PostgreSQLドキュメントへのリンク)。
このクエリは、私が探している望ましい出力を私に与えます:
select *
from service except (
select s1.*
from service s1, service s2
where s1.price > s2.price
)
エラーがどこにあるか私に指示するどんな援助でも大歓迎です!
CTE(共通テーブル式)はビューのようなものであり、他のビュー(またはテーブル)のように扱う必要があります。 EXCEPTの2番目の部分として、完全なSELECTステートメントが必要です。
with expensive_service as (
select s1.*
from service s1, service s2
where s1.price > s2.price
)
select *
from service
except
select *
from expensive_service;
UNION、EXCEPT、またはINTERSECTの個々の部分を囲む括弧は不要です(onlyクエリにORDER BYが必要な場合を除きます)。 LIMIT句を使用しています)。
したがって、元のクエリは(私の意見では)、次のように書くこともできます
select *
from service
except
select s1.*
from service s1, service s2
where s1.price > s2.price
このクエリは、私が探している望ましい出力を私に与えます:
代わりにこれを使用してください!
SELECT *
FROM service
WHERE price = (SELECT min(price) FROM service)
-- OR price IS NULL -- add if price can be NULL
テーブルが大きい場合は、(price)
にインデックスがあることを確認してください。
現在受け入れられている回答には優れた技術情報がありますが、実際のクエリは使用しないでください。また、通常はEXCEPT
ではなくEXCEPT ALL
が必要です。見る:
しかし、しないでください。
2番目のSELECT
の暗黙のCROSS JOIN
は、O(N²)でスケーリングされます。それは何をするためのものか?
...
SELECT s1.*
FROM service s1, service s2
WHERE s1.price > s2.price
これにより、テーブル内のprice
が小さい(またはprice IS NULL
)の行ごとに、すべての行のコピーが1つ返されます。何のために?次のステップでそれらを除外します。つまり、価格が最も小さい行(またはprice IS NULL
)のみが除外されません。言い換えると:
最小のprice
(またはprice IS NULL
)を持つすべての行を取得します。
関連: