У меня есть простая (я полагаю) проблема, которая сбивает меня с толку (я не эксперт по SQL, как вы скоро увидите ... :-).
У меня есть таблица person
с полями id
и name
и таблица comment
с полями id
, id_person
и text
:
---------------
table: person
---------------
id | name
---------------
---------------------------
table: comment
---------------------------
id | id_person | text
---------------------------
Комментарии связаны с людьми на person.id
=> comment.id_person
.
У каждого человека может быть много комментариев.
Я бы предпочел не сохранять количество комментариев в любой таблице.
Возникает вопрос: Как выбрать всех людей, у которых есть не менее N комментариев?
Это то, что я сейчас пытаюсь, но это конечно неправильно ...:
SELECT * FROM person WHERE (SELECT COUNT(*) FROM comment WHERE id_person = 2) >= N
P.S .: Сейчас я работаю с sqlite, но стандартный ответ SQL подойдет ...
3 ответа
Я не уверен, что понимаю, что не так с тем, что вы пробовали. Вы жестко кодируете идентификатор, но если вы просто замените его, все будет в порядке.
SELECT *
FROM person
WHERE (SELECT COUNT(*)
FROM comment
WHERE id_person = person.id) >= N
Другое решение, лучше или нет, трудно определить (вы должны попробовать каждое, если производительность вызывает беспокойство, или, по крайней мере, проверить планы запросов), - это использовать предложение GROUP BY
:
SELECT *
FROM person
WHERE id IN (SELECT id_person
FROM comment
GROUP BY id_person
HAVING COUNT(*) >= N)
Мне нравится использовать здесь предложение IN
по сравнению с INNER JOIN
, потому что оно позволяет вам делать SELECT *
, как в вашем примере. Конечно, это может иногда не быть идеальным, но похоже, что это подходит для вашего случая.
В каждом из них, конечно же, вам придется заменить N
параметром или буквальным значением.
DECLARE @N INT--Here I declared variable N, but you could simply hardcode the value instead.
SELECT @N = 2
select person.id,
person.name
from person
INNER JOIN comment ON person.id = comment.id_person
GROUP BY person.id,
person.name
HAVING COUNT(comment.id) >= @N
Проще всего было бы использовать такие предложения group by
и having
select p.name
from person p
inner join comment c on c.id_person = p.id
group by
p.name
having count(*) = 2
В качестве примечания: я бы переименовал ваши столбцы в
---------------------------
table: person
---------------
id_person | name
---------------
---------------------------
table: comment
---------------------------
id_comment | id_person | text
---------------------------
Чтобы было понятно, какие столбцы связаны друг с другом. Когда-нибудь вы столкнетесь с новой для вас схемой базы данных, в которой имена не совпадают, и вам придется прибегать к поиску отношений внешних ключей, чтобы решить эту проблему. Поверьте, это не весело.
Похожие вопросы
Связанные вопросы
Новые вопросы
sql
Язык структурированных запросов (SQL) - это язык запросов к базам данных. Вопросы должны включать примеры кода, структуру таблицы, примеры данных и тег для используемой реализации СУБД (например, MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2 и т. Д.). Если ваш вопрос относится исключительно к конкретной СУБД (использует определенные расширения / функции), используйте вместо этого тег этой СУБД. Ответы на вопросы, помеченные SQL, должны использовать стандарт ISO / IEC SQL.