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


104

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

サプライヤー(sid:整数、sname:文字列、アドレス文字列)

Parts(pid:整数、pname:文字列、color:文字列)

Catalog(sid:integer、pid:integer、cost:real)

(主キーは太字です)

私は、少なくとも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-グループ関数の無効な使用

何が悪いのですか?

回答:


173

使用する必要はありHAVINGませんWHERE

違いは、WHERE句はMySQLが選択する行をフィルタリングすることです。次に、 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)

24
また、GROUP BYを使用する場合、HAVINGはGROUP BYの後にある必要があります
Viacheslav '22

1
また、GROUP BYはHAVINGの前にある必要があります。...Bandoleroのコメントを読んでいる必要があります:D
Andrew

8

まず、発生しているエラーは、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

私は、少なくとも2つの行が同じで存在する行のみを返すべきだと考え、どのpidなく、少なくとも2つのがあるさsidsが。pidグループ化句を適用した結果、1行だけが返されるようにしています。


参加すら必要ないのですか?(可能な解決策を提供した私の最新の回答を参照してください。)
Nick Heiner '25

@Rosarch、COUNT(DISTINCT sid)更新したクエリで使用したいと思います。
マークエリオット

sidとにかく一緒に主キーを形成するためsid、とにかく常に区別する必要はありませんか?pidCatalog
Nick Heiner
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.