4

我正在尝试掌握窍门,NOT EXISTS但遇到了一些麻烦。假设我有 2 张桌子。

Employees:
+------+------+
| eid  | name |
+------+------+
| 1    | Bob  |
| 2    | Alice|
| 3    | Jill |
+------+------+

Transactions:
+----------+----------+----------+-----------+
| tid      | eid      | type     | amount    |
+----------+----------+----------+-----------+
| 1        | 1        | Deposit  | 50        |
| 2        | 1        | Open     | 500       |
| 3        | 3        | Open     | 200       |
| 4        | 2        | Withdraw | 25        |
| 5        | 2        | Open     | 100       |
+----------+----------+----------+-----------+

假设我要查找所有未开立账户且金额为 250 美元或更高的员工的姓名。这意味着我只想要员工开设金额 < 250 美元的账户的行。现在我有这样的东西......

SELECT name FROM Employees e
WHERE NOT EXISTS (
SELECT * FROM Transactions t
WHERE t.type <> 'Open' AND t.amount >= 250 AND t.eid = e.eid);

这显然是错误的,我真的不明白为什么。

4

3 回答 3

1

您需要将 aEXISTS与 a结合起来,NOT EXISTS因为您“只需要员工开设金额 < 250 美元的帐户的行。”:

SELECT name FROM Employees e
WHERE EXISTS (
   SELECT 1 FROM Transactions t
   WHERE t.amount < 250 AND t.type='Open' AND t.eid = e.eid)
AND NOT EXISTS (
   SELECT 1 FROM Transactions t
   WHERE t.amount >= 250 AND t.eid = e.eid);

您需要EXISTS确保只返回具有金额 < 250 的未结账户的员工。NOT EXISTS需要确保不包括具有金额 >= 250 的额外帐户的员工。

这是一个 sql-fiddle 演示

于 2012-11-18T21:25:02.980 回答
0

我看到的唯一问题是您使用<>了交易类型,而不是=

SELECT name FROM Employees e
WHERE NOT EXISTS (
SELECT null FROM Transactions t
WHERE t.transaction_type = 'Open' AND t.amount >= 250 AND t.eid = e.eid);

编辑问题后,答案将是:

SELECT name FROM Employees e
WHERE EXISTS (
SELECT null FROM Transactions t
WHERE t.transaction_type = 'Open' AND t.amount < 250 AND t.eid = e.eid);
于 2012-11-18T21:13:10.593 回答
0

我建议使用 LEFT JOIN 而不是子选择。

SELECT name FROM Employees e
LEFT JOIN Transactions t
ON e.eid = t.eid
WHERE t.tid IS NULL
OR t.type <> 'Open'
OR t.amount <= 250;

这将连接所有交易记录,然后只包括不存在交易、用户有未打开交易或金额不符合要求的记录 $250

于 2012-11-18T21:41:51.100 回答