Думайте об этом поэтапно.
Сначала мы найдем месяцы, в которых более одного дня рождения.Это подзапрос ниже, который я называю псевдонимом i
для «внутреннего запроса».(Замените MONTH(i.Birthdate)
в списке SELECT
на 1
, если вы хотите увидеть, какие месяцы соответствуют критериям.)
Затем во внешнем запросе (o
) вы захотите все поля,так что я обманываю и использую SELECT *
.Теоретически, WHERE IN
будет работать здесь, но IN
может иметь неприятные побочные эффекты, если NULL
вернется, поэтому я никогда не буду его использовать.Вместо этого есть коррелированный sub = запрос;то есть мы ищем любые результаты, в которых месяц из внешнего запроса равен месяцам, которые делают сокращение во внутреннем (коррелированном под) запросе.
При использовании коррелированного подзапроса вWHERE
предложение, список SELECT
не имеет значения.Вы можете поставить 1/0
, и он не выдаст ошибку.Но я всегда использую SELECT 1
, чтобы показать, что внутренний запрос фактически не возвращает никаких результатов во внешний запрос.Это просто для того, чтобы найти, ну, в общем, корреляцию между двумя наборами данных.
SELECT
*
FROM
@table AS o
WHERE
EXISTS
(
SELECT
1
FROM
@table AS i
WHERE
MONTH(i.Birthdate) = MONTH(o.Birthdate)
GROUP BY
MONTH(i.Birthdate)
HAVING
COUNT(*) > 1
);