2

Customer、Product、およびTransactionテーブルで構成されるデータベースがあります。

私は、2000年にトランザクションを行わなかった顧客のすべての顧客の名前とSSNを一覧表示するSQLステートメントを作成しようとしています。

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

アプローチを変えたいと思います。

次のクエリは必要ありません。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'
  )
于 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

このクエリは、トランザクションを顧客に結合しますが、特に2000年から結合します。したがってTransactions、パッチの記録がない顧客は、その年にトランザクションがありませんでした。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 に答える