2

関連する場合は、SQL*Plus または Oracle 11g Express を使用しています。

私はSQLに慣れていないので、ネストされたグループ関数についてもっと知りたいという奇妙なことに出くわしました。エラーの皮肉とその解決策が興味深いことがわかりました。

これは動作しません

where
t1.col1 =
    (select col1
    from t2
    having count(col2) = max(count(col2))
group by col1
;

上記で、私は受け取ります:

ORA-00935: グループ関数のネストが深すぎます

これは機能します

where
t1.col1 =
    (select col1
    from t2
    having count(col2) =
        (select max(count(col2)) from t2 
        group by col1)
    group by t2.col1)
;

上記を踏まえて、2つの質問があります。

1)コンパイラ/アプリケーションが混乱する正確な方法/場所は?

2)明確にするためだけに、より深いサブクエリが最初に「起動」し、上位のサブクエリの値を返すと仮定して、混乱を完全にスキップするのは正しいですか?

4

1 に答える 1

2
  1. コンパイラは混乱していません。

    エラーは、集約関数がそのコンテキストでは意味をなさないという事実を単に警告しています。

    having count(col2) = max(count(col2)
    

    HAVING句はGROUPBYの後に有効になるため、の個別の値ごとCOUNT(COL2)に列内のnull以外の値の数も有効になります。の1つの明確な値のコンテキストでは、意味がありません-結果が3の場合、明らかに3です-しかし、ここでは、コンパイラは、おそらくそのように意図していなかったことを知るのに十分賢いです。COL2col1col1MAX(COUNT(COL2))COUNT(COL2)MAX(3)

    つまり、あなたが意図していたのCOUNT(COL2)は、左側のはCOL1)のその明確な値に対してであると想定されていたCOUNT(COL2)のに対し、右側のはのすべての値を超えていると想定されていたということですCOL1。したがって、式全体は混合であり、有効なSQLではありません。

  2. はい、必要に応じてそのように考えることができます。最も深いサブクエリが最初に実行され、呼び出し元のサブクエリに結果セット(この場合は単一の行と単一の列)が返されます。

テーブルに対して2つのクエリを効果的に実行する代わりに、次のクエリの方が効率的であることがわかります。

where t1.col1 =
  (select col1
   from   (select col1, count_col2, MAX(count_col2) OVER () max_count_col2
           from   (select col1,
                          count(col2) AS count_col2
                   from t2
                   GROUP BY col1))
   where  count_col2 = max_count_col2)
于 2012-12-10T07:34:36.360 に答える