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-グループ関数の無効な使用
私は何を間違えていますか?
HAVING
ではなく、WHERE
を使用する必要があります。
違いは:WHERE
句は、MySQLが選択する行をフィルタリングします。 Then MySQLは行をグループ化し、COUNT
関数の数値を集計します。
HAVING
はWHERE
に似ていますが、発生するのは後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)
まず、発生しているエラーは、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つのsid
sがある行のみを返す必要があると思います。 pid
ごとに1行のみが返されるように、グループ化句を適用しました。