MySQL: неверное использование групповой функции - PullRequest
87 голосов
/ 25 февраля 2010

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

Поставщики ( sid: целое число , sname: строка, строка адреса)

Детали ( pid: целое число , pname: строка, цвет: строка)

Каталог ( sid: целое число, pid: целое число , стоимость: действительное)

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

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

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

Что я делаю не так?

Ответы [ 2 ]

150 голосов
/ 25 февраля 2010

Вам нужно использовать HAVING, а не WHERE.

Разница в том, что предложение WHERE фильтрует, какие строки выбирает MySQL. Затем MySQL группирует строки и объединяет числа для вашей COUNT функции.

HAVING похож на WHERE, только это происходит после the 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)
8 голосов
/ 25 февраля 2010

Во-первых, ошибка, которую вы получаете, связана с тем, где вы используете функцию 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, я применил условие группировки.

...