SELECT column_name(s)
FROM table_name
WHERE EXISTS
(SELECT column_name FROM table_name WHERE condition);
Websites;
+----+--------------+---------------------------+-------+---------+
| id | name | url | alexa | country |
+----+--------------+---------------------------+-------+---------+
| 1 | Google | https://www.google.cm/ | 1 | USA |
| 2 | 淘宝 | https://www.taobao.com/ | 13 | CN |
| 3 | 菜鸟教程 | http://www.runoob.com/ | 4689 | CN |
| 4 | 微博 | http://weibo.com/ | 20 | CN |
| 5 | Facebook | https://www.facebook.com/ | 3 | USA |
+----+--------------+---------------------------+-------+---------+
access_log;
+-----+---------+-------+------------+
| aid | site_id | count | date |
+-----+---------+-------+------------+
| 1 | 1 | 45 | 2016-05-10 |
| 2 | 3 | 100 | 2016-05-13 |
| 3 | 1 | 230 | 2016-05-14 |
| 4 | 2 | 10 | 2016-05-14 |
| 5 | 5 | 205 | 2016-05-14 |
| 6 | 4 | 13 | 2016-05-15 |
| 7 | 3 | 220 | 2016-05-15 |
| 8 | 5 | 545 | 2016-05-16 |
| 9 | 3 | 201 | 2016-05-17 |
+-----+---------+-------+------------+
9 rows in set (0.00 sec)
-- 查找总访问量(count 字段)大于 200 的网站是否存在
SELECT Websites.name, Websites.url
FROM Websites
WHERE EXISTS (SELECT count FROM access_log WHERE
Websites.id = access_log.site_id
AND count > 200);
-- 查找总访问量(count 字段)小于 200 的网站是否存在
SELECT Websites.name, Websites.url
FROM Websites
WHERE NOT EXISTS (SELECT count FROM access_log
WHERE Websites.id = access_log.site_id AND count > 200);
从Websites表中选择name和url两个字段的值,并且通过EXISTS子查询来筛选出在access_log表中对应的记录中访问次数大于200的网站。
具体来说,子查询中的SELECT count FROM access_log WHERE Websites.id = access_log.site_id AND count > 200语句会返回一个数字,表示访问次数大于200的网站在access_log表中出现的次数。如果这个数字大于0,那么说明存在访问次数大于200的网站,EXISTS子查询返回的结果为真,WHERE子句就会过滤掉这些网站,只返回访问次数不大于200的网站。
最终,查询结果包括Websites.name和Websites.url两个字段的值,表示访问次数不大于200的网站的名称和URL。
EXISTS子查询可以用来检查一个查询是否返回了至少一行记录,它通常用在WHERE子句中。如果你觉得理解起来比较费劲,可以尝试使用JOIN子句来代替。
例如,假设你想查询在access_log表中访问次数大于200的网站,可以使用以下查询语句:
SELECT Websites.name, Websites.url
FROM Websites
JOIN (
SELECT site_id, COUNT(*) AS count
FROM access_log
GROUP BY site_id
HAVING COUNT(*) > 200
) AS al ON Websites.id = al.site_id;
这个查询语句中,子查询使用GROUP BY子句和COUNT函数来计算每个网站在access_log表中的访问次数,并且只选择访问次数大于200的记录。然后,外层查询使用JOIN子句将Websites表和子查询的结果连接起来,只选择访问次数大于200的网站。这种方法可能会比EXISTS子查询更容易理解和维护。
UPDATE
在 SQL 中,EXISTS 关键字通常用于在 UPDATE 语句中检查子查询的结果是否存在。下面是一个使用 EXISTS 的双表 UPDATE 示例:
假设我们有两个表,一个是 employees 表,包含员工的基本信息,另一个是 salary_changes 表,包含员工的薪水变化信息。我们想要更新 employees 表中的薪水,根据 salary_changes 表中的薪水变化条件。
-- 创建示例表 employees
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
employee_name VARCHAR(50),
salary INT
);
-- 创建示例表 salary_changes
CREATE TABLE salary_changes (
employee_id INT,
salary_change_amount INT
);
-- 插入一些示例数据
INSERT INTO employees VALUES (1, 'Alice', 50000);
INSERT INTO employees VALUES (2, 'Bob', 60000);
INSERT INTO salary_changes VALUES (1, 1000);
INSERT INTO salary_changes VALUES (2, 1500);
现在,我们可以使用 EXISTS 关键字来更新 employees 表中的薪水:
-- 两个表就是这么写的,通过子查询知道自己增减多少钱
UPDATE employees
SET salary = salary + (SELECT salary_change_amount FROM salary_changes WHERE salary_changes.employee_id = employees.employee_id)
WHERE EXISTS (SELECT 1 FROM salary_changes WHERE salary_changes.employee_id = employees.employee_id);
-- 在 EXISTS 子查询中,通常是用来检查子查询是否返回结果,而不涉及到具体的连接条件。
-- 这是因为 EXISTS 关键字只关心子查询是否返回了结果,而不关心结果的具体内容。
UPDATE employees
SET salary = salary + 1000 -- 假设薪水变化是 1000
WHERE EXISTS (SELECT 1 FROM salary_changes WHERE salary_changes.employee_id = employees.employee_id);
这个 UPDATE 语句的作用是,对于 salary_changes 表中存在记录的员工,在 employees 表中将其薪水增加相应的薪水变化值。这里使用了 EXISTS 子查询来检查是否存在符合条件的薪水变化记录。