MySQL: недопустимое использование групповой функции

Я использую MySQL. Вот моя схема:

Поставщики ( sid: integer, sname: строка, адресная строка)

Части ( pid: integer, pname: строка, цвет: строка)

Каталог ( sid: integer, pid: integer, стоимость: реальная)

(первичные ключи выделены полужирным шрифтом)

Я пытаюсь написать запрос, чтобы выбрать все части, которые сделаны как минимум двумя поставщиками:

-- 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 - Недействительное использование групповой функции

Что я делаю неправильно?

Ответ 1

Вам нужно использовать 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)

Ответ 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 sid s. Чтобы убедиться, что вы вернулись только к одной строке за pid, я применил предложение группировки.