2017-05-10 8 views
1

ALLサブクエリを含むWHERE句の条件があります。サブクエリの結果が空の場合は、式は常にtrueと評価されますが、評価する値はfalseです。postgresql ALLサブクエリーが空で真に評価されます

たとえば、ドライバのテーブル、ルートのテーブル、および各ドライバが駆動したルートを示す多対多の対話テーブルがあるとします。私は、50マイル以上のルートしか運転していないドライバーを探したい。

SELECT * FROM driver 
WHERE 50 < ALL(
    SELECT miles FROM route, driver_route 
    WHERE driver_route.route_id = route.id AND 
      driver_route.driver_id = driver.id) 

このクエリには、結果にルートが表示されていないドライバが含まれますが、これは私が望まないものです。

私はcoalesceを使ってみましたが、ERROR: more than one row returned by a subquery used as an expressionに走りました。

SELECT * FROM driver 
WHERE 50 < COALESCE((
    SELECT ALL(SELECT miles FROM route, driver_route 
    WHERE driver_route.route_id = route.id AND 
      driver_route.driver_id = driver.id)), 
    0); 

私はさまざまな種類とクエリに適用されるのに十分一般的だ構造を探しています:ここでは、私はそのクエリを言葉で表現する方法です。

答えて

1

何についてこの

SELECT * FROM driver 
WHERE NOT EXISTS ( 
    SELECT miles FROM route, driver_route 
    WHERE driver_route.route_id = route.id AND 
      driver_route.driver_id = driver.id AND 
      miles <= 50 
       ) 
AND EXISTS ( 
    SELECT miles FROM route, driver_route 
    WHERE driver_route.route_id = route.id AND 
      driver_route.driver_id = driver.id AND 
      miles > 50 
       ) 

全50よりも大きいことは、私はあなたがこの必要があると思う50

+0

感謝を。結果は同じです。私が正しく理解していれば、このクエリには空の結果が明示的に含まれています。これは私が避けようとしているものです。 – user3747260

+0

@ user3747260は、少なくとも1つの「マイル> 50」を要求するために「AND EXISTS」に適合しています。もちろん、 – flutter

+0

です。重複しているにもかかわらず、クエリプランナーはこれをうまく処理しているようです。私はこれが一般的な問題ではなく、より標準的な解決策ではないことに驚いていると言わなければならないが、あなたはうまくいくようだ。ありがとう。 – user3747260

2

に小さいか等しいことなしに相当します。お返事を

select driver.* from driver inner join (
    select driver.id from driver 
    inner join driver_route 
    on driver.id = driver_route.driver_id 
    inner join route 
    on route.id = driver_route.route_id 
    group by driver.id 
    having min(route.miles) > 50 
)t 
on driver.id = t.id 
+0

これは興味深いアプローチであり、動作します。残念ながら、私はさまざまなタイプに適用できる同じ構造の一般的なソリューションを探していますし、minの使用はかなり複雑です。 – user3747260

関連する問題