web-dev-qa-db-ja.com

GROUP BYステートメントのワイルドカードが機能しないのはなぜですか?

次のSQLステートメントを機能させようとしていますが、構文エラーが発生します。

SELECT A.*, COUNT(B.foo)
FROM TABLE1 A
LEFT JOIN TABLE2 B ON A.PKey = B.FKey
GROUP BY A.*

ここで、Aは40列の幅の広いテーブルであり、可能な場合はGROUP BY句に各列名をリストしないようにします。同様のクエリを実行する必要があるテーブルがたくさんあるので、ストアドプロシージャを作成する必要があります。これに取り組む最善の方法は何ですか?

MS SQL Server 2008を使用しています。

29

GROUP BY A.*はSQLでは使用できません。

グループ化するサブクエリを使用してこれをバイパスし、結合することができます。

SELECT A.*, COALESCE(B.cnt, 0) AS Count_B_Foo
FROM TABLE1 AS A
  LEFT JOIN 
      ( SELECT FKey, COUNT(foo) AS cnt
        FROM TABLE2 
        GROUP BY FKey
      ) AS B 
    ON A.PKey = B.FKey ;

SQL-2003標準には、機能的に依存している限り、SELECTリスト、GROUP BYリストにない列を許可する機能があります。その機能がSQL-Serverに実装されている場合、クエリは次のように記述できます。

SELECT A.*, COUNT(B.foo)
FROM TABLE1 A
LEFT JOIN TABLE2 B ON A.PKey = B.FKey
GROUP BY A.pk                          --- the Primary Key of table A

残念ながら、この機能はまだ実装されておらず、SQL-Server 2012バージョンでも実装されていません。また、私の知る限り、他のどのDBMSにも実装されていません。それを持っているが不十分であるMySQLを除いて(不適切として:上記のクエリは機能しますが、エンジンは機能依存性のチェックを行わず、他の不適切なクエリは誤ったセミランダムな結果を表示します)。

@ Mark Byers がコメントで私たちに知らせたように、PostgreSQL 9.1は新しい機能を追加しましたのために設計されましたこの目的。 MySQLの実装よりも制限があります。

32
ypercubeᵀᴹ

@ypercubeの回避策に加えて、「タイピング」はSELECT *を使用するための言い訳にはなりません。私は これについてここに書いてあります であり、回避策を使用しても、SELECTリストには列名が含まれているはずです-40のような膨大な数がある場合でも。

要するに、オブジェクトエクスプローラーのオブジェクトの列ノードをクリックしてクエリウィンドウにドラッグすることで、これらの大きなリストを入力する手間を省くことができます。スクリーンショットはビューを示していますが、テーブルについても同じことができます。

enter image description here

しかし、すべての理由whyについて読みたい場合は、アイテムを数インチドラッグするという膨大なレベルの労力を自分に課す必要があります 私の投稿をお読みください 。 :-)

24
Aaron Bertrand