2012-04-19 2 views
2

У меня есть база данных, состоящая из таблицы Customer, Product и Transaction.SQL Datetime Not Equal To Not Working

Я пытаюсь написать заявление SQL, чтобы перечислить имена всех клиентов и ПЛА для тех клиентов, которые не сделали ни одной сделки в 2000 году

Столбец TransactionDate в таблице транзакций является дата/время тип данных (например, 2000-12-18 00:00:00).

Это SQL код, который я написал:

SELECT DISTINCT CustomerName, Customer.CustomerSSN 
FROM Customer, Transaction 
WHERE Customer.CustomerSSN=Transaction.CustomerSSN 
AND YEAR(TransactionDate)<>2000; 

Не равно символу (<>), кажется, не работает по какой-то причине. Когда я меняю его на знак равенства, он возвращает правильный результат ...

Любые советы приветствуются.

+4

определить «не работает». У вас есть записи с годом <> 2000? –

+1

Логика вашего SQL-запроса не соответствует вашей постановке проблемы. Он возвращает клиентов с транзакциями за 2000 год *, даже если они также имели транзакцию в 2000 * (а не то, что вы хотите). Ниже приведены ответы на все пути получения желаемого результата. –

ответ

4

Я бы изменил подход.

Следующий запрос не нужен distinct или GROUP BY, потому что ни одна из записей клиента не соединена с несколькими записями транзакций.

Он также работает для клиентов, которые никогда не совершали никаких транзакций.

И, наконец, он использует >= AND <, а не YEAR()=2000. Это позволяет искать индекс, а не полное сканирование (при условии, что у вас есть индекс индекса в таблице транзакций).

SELECT 
    CustomerName, 
    CustomerSSN 
FROM 
    Customer 
WHERE 
    NOT EXISTS (
    SELECT * 
     FROM Transaction 
    WHERE CustomerSSN  = Customer.CustomerSSN 
     AND TransactionDate >= '20000101' 
     AND TransactionDate < '20010101' 
) 
+0

Работает отлично, спасибо – user994585

2
SELECT DISTINCT 
    Customer.CustomerName, 
    Customer.CustomerSSN 
FROM Customer 
LEFT JOIN Transaction 
    ON Customer.CustomerSSN=Transaction.CustomerSSN 
    AND YEAR(TransactionDate) = 2000 
WHERE Transaction.TransactionDate IS NULL 

Этот запрос присоединяется к операции на клиент, однако присоединяется к специально Transactions с 2000 года, следовательно, любые клиенты, которые не имеют зашивок записи из Transactions не были сделки в этом году. Поэтому вы ищете Transaction.TransactionDate IS NULL

В своем собственном запросе вы просто находите тех клиентов, у которых были транзакции за год, который не был 2000, однако некоторые из них также имели транзакции в 2000 году.

1
SELECT CustomerName, CustomerSSN 
FROM Customer 
WHERE CustomerSSN NOT IN (
SELECT CustomerSSN 
FROM Transaction 
WHERE Year(TransactionDate)=2000); 
+2

'WHERE TransactionDate = 2000' не будет работать. Вы хотели бы скопировать 'YEAR (TransactionDate) = 2000'? Если да, то также обратите внимание, что это не SARGable. – MatBailie

+0

Хорошо, я исправил свой ответ. –

0

Я знаю ее решить, но все же хотел отправить это как дополнительный ответ здесь (может быть полезным для других).

Альтернативный способ исправить это - использовать оператор NULLIF, который является наименее модифицированным исходным запросом, и я предполагаю, что это будет лучшая замена, если <> не работает.

SELECT DISTINCT CustomerName, Customer.CustomerSSN 
FROM Customer, Transaction 
WHERE Customer.CustomerSSN=Transaction.CustomerSSN 
AND (NULLIF(YEAR(TransactionDate), 2000) IS NOT NULL)