我有一个由Customer,Product和Transaction表组成的数据库。
我正在尝试编写一个SQL语句来列出所有客户的名称和SSN用于那些在2000年没有进行任何交易的客户。
Transaction表中的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;
不等于符号(&lt;&gt;)似乎由于某种原因不起作用。当我将其更改为等号时,它会返回正确的结果...
感谢任何建议。
答案 0 :(得分:4)
我会改变方法。
以下查询不需要distinct
或GROUP BY
,因为没有客户记录加入多个交易记录。
它也适用于从未进行任何交易的客户。
最后,它使用>= AND <
而不是YEAR()=2000
。这启用索引搜索而不是完整扫描(假设您在事务表上有一个approriate索引)。
SELECT
CustomerName,
CustomerSSN
FROM
Customer
WHERE
NOT EXISTS (
SELECT *
FROM Transaction
WHERE CustomerSSN = Customer.CustomerSSN
AND TransactionDate >= '20000101'
AND TransactionDate < '20010101'
)
答案 1 :(得分: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
此查询将事务连接到客户,但是从2000年开始专门加入Transactions
。因此,Transactions
没有修补记录的任何客户在该年没有交易。因此,您正在寻找Transaction.TransactionDate IS NULL
在您自己的查询中,您只是找到一年中非2000年交易的客户,但有些客户也可能在2000年内进行了交易。
答案 2 :(得分:1)
SELECT CustomerName, CustomerSSN
FROM Customer
WHERE CustomerSSN NOT IN (
SELECT CustomerSSN
FROM Transaction
WHERE Year(TransactionDate)=2000);
答案 3 :(得分:0)
我知道它已经解决了,但仍然想在此发布这个作为补充答案(可能对其他人有帮助)。
另一种解决方法是使用NULLIF运算符,这是对原始查询的最小修改,如果&lt;&gt;,我认为它是更好的替代方法。不起作用。
--volumes-from