Правильный запрос: первый .
Как отметил пользователь 2722968, использование: WHERE YEAR(orderdate) = '2007' AND YEAR(orderdate) <> '2008'
работает для каждой строки.Таким образом, если у custid есть и orderid в 2007 году, и другой в 2008 году, вышеупомянутый WHERE
действительно вернет строку 2007 года, так как он действительно YEAR(orderdate) = '2007' AND YEAR(orderdate) <> '2008'
.
Наоборот, разные коды в(NOT) EXISTS
выполнить операцию (semijoi) не над строками, а над наборами результатов.Это то, что вам нужно.
Предложение: Рекомендуется не использовать функции, если вы можете их избегать, потому что, когда вы применяете функции к полю, если на нем есть индекс, он не можетбыть использованы для ускорения расчетов.Таким образом, вместо YEAR (orderdate) = 2007 лучше использовать:
orderdate>='20070101' and orderdate<'20080101'
С учетом этого запрос становится:
SELECT custid, companyname
FROM customers c
WHERE EXISTS
(SELECT custid
FROM orders o
WHERE orderdate>='20070101' and orderdate<'20080101' AND o.custid = c.custid)
AND NOT EXISTS
(SELECT custid
FROM orders o
WHERE orderdate>='20080101' and orderdate<'20090101' AND o.custid=c.custid)