2

我有一个由 Customer、Product 和 Transaction 表组成的数据库。

我正在尝试编写一条 SQL 语句来列出那些在 2000 年没有进行交易的客户的所有客户的姓名和 SSN。

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;

不等于符号 (<>) 似乎由于某种原因不起作用。当我将其更改为等号时,它确实返回了正确的结果......

任何建议表示赞赏。

4

4 回答 4

4

我会改变方法。

以下查询不需要distinctGROUP BY因为没有客户记录连接到多个交易记录。

它也适用于从未进行过任何交易的客户。

最后,它使用>= AND <而不是YEAR()=2000. 这启用了索引查找而不是完全扫描(假设您在 transactions 表上有一个适当的索引)

SELECT
  CustomerName,
  CustomerSSN
FROM
  Customer
WHERE
  NOT EXISTS (
    SELECT *
      FROM Transaction
     WHERE CustomerSSN      = Customer.CustomerSSN
       AND TransactionDate >= '20000101'
       AND TransactionDate <  '20010101'
  )
于 2012-04-19T12:41:10.640 回答
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 年内进行过交易。

于 2012-04-19T12:39:27.380 回答
1
SELECT CustomerName, CustomerSSN 
FROM Customer
WHERE CustomerSSN NOT IN (
SELECT CustomerSSN
FROM Transaction
WHERE Year(TransactionDate)=2000);
于 2012-04-19T12:42:35.303 回答
0

我知道它已解决,但仍想在此处发布此作为附加答案(可能对其他人有帮助)。

解决此问题的另一种方法是使用 NULLIF 运算符,这是对原始查询的最少修改,如果 <> 不起作用,我认为它是更好的替代品。

SELECT DISTINCT CustomerName, Customer.CustomerSSN 
FROM Customer, Transaction
WHERE Customer.CustomerSSN=Transaction.CustomerSSN
AND (NULLIF(YEAR(TransactionDate), 2000) IS NOT NULL)
于 2015-08-28T11:40:03.953 回答