了解NOT EXISTS

时间:2012-11-18 21:11:35

标签: mysql sql sqlplus

我正试图抓住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美元或更高金额账户的员工的姓名。这意味着我只想要员工开设账户金额<1的行。 $ 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);

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

3 个答案:

答案 0 :(得分:1)

您需要将EXISTSNOT 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以确保只返回具有金额<1的未结账户的员工。总共250。 NOT EXISTS是必需的,以确保不包含员工,其中包含金额> = 250的其他帐户。

Here's a sql-fiddle demo

答案 1 :(得分: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);

答案 2 :(得分: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美元