2015-10-30 9 views
5

SQLクエリでHAVING句を使用して、行のグループをフィルタすることができました。 GROUP BY句を使用すると、このように直接動作します。HAVING句は実際にどのように機能しますか?

しかし、のは、このクエリを見てみましょう:

select 1 where 1!=1 having count(*)=0; 

(またはOracleのための 'デュアルから' でそれを追加)。

HAVINGが実際にグループフィルタリングを行う場合、WHEREには行がないため、グループがなく、結果に 'No row selected'を指定する必要があります。

しかし、PostgreSQLでは、MySQLとOracleはクエリの結果として「1」を取得します。

質問:HAVINGは実際にどのように機能しますか?テストのための

SQLフィドル:http://www.sqlfiddle.com/#!15/d5407/51

+0

愚かな方法を参照してください... – jarlh

+0

リターン0行であるため、0行の行があります。HAVINGが行のフィルタリングのみを行えば、なぜスタートで空の入力に対して何らかの評価を行うのですか? – potapuff

答えて

7

select 1 
where 1!=1 
having count(*)=0; 

が実際のようなものです。

この列には、あなたの選択リストにはありませんが、ハードコードされたリテラル1

select count(*) where 1!=1 ; 
select 'bla' where 1!=1 having count(*)=0; 

テーブルが0行であるかそうでないかを検出するfiddle

+0

GROUP BYのないHAVINGが、 – potapuff

+0

@potapuff:一致する行がない場合、 'COUNT'はゼロ、' SUM'、 'MIN'などを返します。 – dnoeth

3

HAVINGGROUP BYなしcluaseが有効であり、全体のテーブルの上に動作します。 92 SQL規格から:

7.10

:: =

構文規則を持つことは

1)HCは、とします。 TEにすぐにHCが含まれるようにします。

TEにすぐにaが含まれない場合、GROUP BY()は暗黙的です。

と:

:: = GROUP

<grouping specification> ::= 
<grouping column reference> 
    | <rollup list> 
    | <cube list> 
    | <grouping sets list> 
    | <grand total> 
    | <concatenated grouping> 

<grouping set> ::= 
<ordinary grouping set> 
    | <rollup list> 
    | <cube list> 
    | <grand total> 

<grand total> ::= <left paren> <right paren> 

あなたがGROUP BY()を見たよう

BYは grand totalとして扱われます。あなたの例では

あなたが持っている:COUNT(*)戻っ0はあなたのケースでは、集計は常に行を返さないGROUP BYがない場合

select 1 
where 1!=1 
-- group by() 
having count(*)=0; 
+0

ちなみに、ほとんどのデータベース(MySQL、PostgreSQL、Oracle)はGROUP BY()をサポートしていません: – potapuff

関連する問題