web-dev-qa-db-ja.com

MySQL:グループ関数の無効な使用

MySQLを使用しています。これが私のスキーマです:

サプライヤー(sid:整数、sname:文字列、住所文字列)

パーツ(pid:integer、pname:string、color:string)

カタログ(sid:整数、pid:整数、コスト:実数)

(主キーは太字になっています)

少なくとも2つのサプライヤによって作成されたすべてのパーツを選択するクエリを作成しようとしています。

-- Find the pids of parts supplied by at least two different suppliers.
SELECT c1.pid                      -- select the pid
FROM Catalog AS c1                 -- from the Catalog table
WHERE c1.pid IN (                  -- where that pid is in the set:
    SELECT c2.pid                  -- of pids
    FROM Catalog AS c2             -- from catalog
    WHERE c2.pid = c1.pid AND COUNT(c2.sid) >= 2 -- where there are at least two corresponding sids
);

最初に、私はこれについても正しい方法で行っていますか?

第二に、私はこのエラーを受け取ります:

1111-グループ関数の無効な使用

私は何を間違えていますか?

88
Nick Heiner

HAVINGではなく、WHEREを使用する必要があります。

違いは:WHERE句は、MySQLが選択する行をフィルタリングします。 Then MySQLは行をグループ化し、COUNT関数の数値を集計します。

HAVINGWHEREに似ていますが、発生するのはCOUNTの値が計算されているため、期待どおりに動作します。サブクエリを次のように書き換えます。

(                  -- where that pid is in the set:
SELECT c2.pid                  -- of pids
FROM Catalog AS c2             -- from catalog
WHERE c2.pid = c1.pid
HAVING COUNT(c2.sid) >= 2)
151
rjh

まず、発生しているエラーは、COUNT関数を使用している場所が原因です。WHERE句で集計(またはグループ)関数を使用することはできません。

次に、サブクエリを使用する代わりに、テーブルをそれ自体に単純に結合します。

SELECT a.pid 
FROM Catalog as a LEFT JOIN Catalog as b USING( pid )
WHERE a.sid != b.sid
GROUP BY a.pid

同じpidを持つ少なくとも2つの行が存在するが、少なくとも2つのsidsがある行のみを返す必要があると思います。 pidごとに1行のみが返されるように、グループ化句を適用しました。

8
Mark Elliot