【SQL入门】成为多条件达人!完全掌握 AND, OR, NOT
“想从数据库里提取特定的数据,但一个条件不够用…”
作为一名Web开发者,在职业进阶的道路上,你是否也曾遇到过这样的瓶颈?
SQL是操作数据库的语言,其中用于提取数据的SELECT语句是基础中的基础。但是,要精准地获取到你真正想要的信息,组合多个条件来筛选数据的技巧是必不可少的。
本文将为你彻底解说用于指定多个条件的三个逻辑运算符——AND、OR、NOT的用法,并附上即使是初学者也能直接复制粘贴运行的示例代码!希望通过“代码成功运行”的体验,让你感受到SQL的乐趣与便捷。
准备:让我们创建一个练习用的表
首先,我们来创建本文将要使用的练习表吧。这是一个虚构的、存放员工信息的employees表。请复制下方的SQL语句,在你自己的数据库环境中执行。
如果手边没有可以立刻尝试的环境也不用担心!文章后半部分我们准备了仅用浏览器就能体验SQL的“SQL执行环境”,所以请先继续往下阅读吧。
-- 如果表已存在,则删除
DROP TABLE IF EXISTS employees;
-- 创建员工表
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(50),
department VARCHAR(50),
position VARCHAR(50),
salary INT,
hire_date DATE
);
-- 插入数据
INSERT INTO employees (id, name, department, position, salary, hire_date) VALUES
(1, '山田 太郎', '営業部', 'マネージャー', 600000, '2018-04-01'),
(2, '鈴木 花子', '開発部', 'エンジニア', 550000, '2020-10-01'),
(3, '佐藤 次郎', '営業部', 'スタッフ', 400000, '2022-04-01'),
(4, '高橋 三郎', '人事部', 'マネージャー', 650000, '2017-07-01'),
(5, '田中 恵子', '開発部', 'デザイナー', 500000, '2021-08-15'),
(6, '伊藤 四郎', '営業部', 'マネージャー', 700000, '2015-02-01'),
(7, '渡辺 久美', '開発部', 'エンジニア', 750000, '2019-06-01'),
(8, '山本 五郎', '人事部', 'スタッフ', 380000, '2023-04-01'),
(9, '中村 さくら', '開発部', 'マネージャー', 800000, '2016-09-01'),
(10, '小林 健太', '営業部', 'スタッフ', 420000, '2023-10-01');
准备好了吗?让我们用这个表来闯入条件指定的世界吧!
1. AND:精准捞取满足所有条件的数据!
AND用中文来说就是“并且”的意思。当你想提取同时满足所有指定条件的数据时,就可以使用它。
例如,“隶属于销售部”并且“职位是经理”的员工信息,就是这样的情况。
基本用法
在WHERE子句中,用AND来连接条件。
SELECT *
FROM employees
WHERE department = '営業部' AND position = 'マネージャー';
执行这条SQL后,就能获取到所有department为'営業部'(销售部)并且position为'マネージャー'(经理)的员工数据。可以看到山田先生和伊藤先生符合条件。
连接多个AND
AND可以连接任意多个。增加的条件越多,数据筛选就越严格。
举个例子,我们来找一下“隶属销售部”并且“职位是经理”并且“工资在650000以上”的员工。
SELECT *
FROM employees
WHERE
department = '営業部'
AND position = 'マネージャー'
AND salary >= 650000;
这次只有伊藤先生被查询出来了。因为增加了条件,山田先生被排除了。就像这样,当需要通过叠加条件来精准定位数据时,AND非常强大。
2. OR:广泛获取满足任一条件的数据!
OR就是“或者”的意思。当你想提取满足指定条件中任意一个的数据时,就可以使用它。
例如,在想要“隶属于销售部”或者“隶属于开发部”的员工列表时,它就能大显身手。
基本用法
用法和AND一样,在WHERE子句中用OR连接条件。
SELECT *
FROM employees
WHERE department = '営業部' OR department = '開発部';
执行后,隶属于'営業部'(销售部)的员工和'開発部'(开发部)的员工都会被显示出来。相对于AND通过叠加条件来筛选,OR给人的感觉是把符合条件的不断加进来。
连接多个OR
当然OR也可以连接多个。我们来找一下“职位是经理”或者“工资在700000以上”的员工。
SELECT *
FROM employees
WHERE position = 'マネージャー' OR salary >= 700000;
这个结果里包含了:
- 职位是经理的人(山田、高桥、伊藤、中村)
- 工资在700000以上的人(伊藤、渡边、中村)
伊藤先生和中村女士同时满足两个条件,当然也会被包含在结果里。OR是一个比较宽松的条件指定,意思是“只要满足至少一个条件就OK”。
3. NOT:提取不符合条件的数据!
NOT顾名思义,就是用来指定“不是…”这样的否定条件。在希望排除掉拥有特定条件的数据时非常方便。
基本用法
在WHERE子句中,把它放在你想要否定的条件前面。
举个例子,我们来获取所有不在“开发部”的员工。
SELECT *
FROM employees
WHERE NOT department = '開発部';
执行这个查询,所有除了'开发部'的员工,也就是'営業部'(销售部)和'人事部'(人事部)的员工,都会被显示出来。
顺便一提,写成WHERE department != '開発部'或WHERE department <> '開発部'也能得到同样的结果。具体使用哪个取决于个人喜好或团队规范,但NOT的特点是能够和IN、EXISTS等其他运算符组合使用,表达范围更广。
【进阶篇】AND与OR的组合及“括号”的重要性
好了,从这里开始是重头戏!通过组合AND和OR,我们可以指定更复杂的条件。但是,这里有一个初学者很容易掉进去的大坑,那就是运算符的优先级。
在SQL中,如果不加任何指定,AND的求值优先级高于OR。这和数学计算中乘法(×)优先于加法(+)很相似。
为了获取到我们预期的结果,和数学一样,使用()(括号)来明确指定优先级就变得至关重要。
错误示例:“隶属销售部或开发部”,并且“职位是经理”的员工是?
如果想当然地把这个条件写成SQL,可能会是这样:
-- 会产生意外结果的SQL
SELECT *
FROM employees
WHERE
department = '営業部'
OR department = '開発部' AND position = 'マネージャー';
这条SQL执行后会怎么样呢?
因为AND优先,SQL会首先计算department = '開発部' AND position = 'マネージャー'(开发部的经理)。然后把这个结果和department = '営業部'(所有销售部员工)用OR连接起来。
也就是说,这个查询实际在找的是:
- ① “销售部”的员工(不限职位)
- ② “开发部”并且是“经理”的员工
结果变成了满足以上两者之一。这和我们最初“销售部或开发部的经理”的意图不一样,对吧?
正确示例:使用括号进行正确分组
要正确地表达“(隶属销售部 或 开发部)并且职位是经理”这个条件,需要把用OR连接的部分用()括起来。
-- 使用括号得到预期的结果!
SELECT *
FROM employees
WHERE
(department = '営業部' OR department = '開発部')
AND position = 'マネージャー';
这样一来,(department = '営業部' OR department = '開発部')会先被计算,形成一个“隶属销售部或开发部”的条件块。然后再对这个结果应用AND position = 'マネージャー'条件,就能正确地提取出“销售部或开发部的经理”了。
混合使用AND和OR时,一定要用括号()明确指定优先级! 请把这当作铁律来记住吧!
实践!在浏览器中运行SQL试试看
久等了!为了让大家能亲手实践至今学到的知识,我们准备了一份礼物。
这是一个使用JavaScript库(AlaSQL.js)制作的、可以在浏览器上直接运行SQL的环境。请把下面的代码完整地复制下来,保存成一个如sql_practice.html这样的文件,然后在浏览器中打开它。
把本文中介绍的各种SQL粘贴到文本框中,点击“执行”按钮,结果就会立刻显示出来。请多多尝试,亲身体验数据的变化吧!
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>SQL练习场</title>
<script src="https://cdn.jsdelivr.net/npm/alasql@4"></script>
<style>
body { font-family: sans-serif; padding: 2rem; background-color: #f9f9f9; }
.container { max-width: 800px; margin: auto; background: white; padding: 2rem; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); }
h1 { color: #333; }
textarea { width: 100%; height: 150px; font-family: monospace; font-size: 16px; padding: 10px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; margin-bottom: 1rem; }
button { background-color: #007bff; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; }
button:hover { background-color: #0056b3; }
#result-area { margin-top: 2rem; }
table { width: 100%; border-collapse: collapse; margin-top: 1rem; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
.error { color: red; font-weight: bold; }
</style>
</head>
<body>
<div class="container">
<h1>来试试SQL吧!</h1>
<p>在下方的文本框中输入SQL语句,然后点击“执行SQL”按钮。来试试文章里介绍的各种SQL吧!</p>
<textarea id="sql-input">-- 在这里输入您的SQL语句
SELECT * FROM employees WHERE (department = '営業部' OR department = '開発部') AND position = 'マネージャー';</textarea>
<button onclick="executeSQL()">执行SQL</button>
<div id="result-area"></div>
</div>
<script>
// 准备数据
const createTableSQL = `
CREATE TABLE employees (
id INT, name STRING, department STRING, position STRING, salary INT, hire_date DATE
);
`;
const insertDataSQL = `
INSERT INTO employees VALUES
(1, '山田 太郎', '営業部', 'マネージャー', 600000, '2018-04-01'),
(2, '鈴木 花子', '開発部', 'エンジニア', 550000, '2020-10-01'),
(3, '佐藤 次郎', '営業部', 'スタッフ', 400000, '2022-04-01'),
(4, '高橋 三郎', '人事部', 'マネージャー', 650000, '2017-07-01'),
(5, '田中 恵子', '開発部', 'デザイナー', 500000, '2021-08-15'),
(6, '伊藤 四郎', '営業部', 'マネージャー', 700000, '2015-02-01'),
(7, '渡辺 久美', '開発部', 'エンジニア', 750000, '2019-06-01'),
(8, '山本 五郎', '人事部', 'スタッフ', 380000, '2023-04-01'),
(9, '中村 さくら', '開発部', 'マネージャー', 800000, '2016-09-01'),
(10, '小林 健太', '営業部', 'スタッフ', 420000, '2023-10-01');
`;
// 初始化AlaSQL数据库
const db = new alasql.Database();
db.exec(createTableSQL);
db.exec(insertDataSQL);
function executeSQL() {
const sql = document.getElementById('sql-input').value;
const resultArea = document.getElementById('result-area');
resultArea.innerHTML = ''; // 清除上一次的结果
try {
const result = db.exec(sql);
if (result.length > 0) {
resultArea.appendChild(createTable(result));
} else {
resultArea.innerHTML = '<p>查询结果为0条记录。</p>';
}
} catch (e) {
resultArea.innerHTML = `<p class="error">错误: ${e.message}</p>`;
}
}
function createTable(data) {
const table = document.createElement('table');
const thead = table.createTHead();
const tbody = table.createTBody();
const headerRow = thead.insertRow();
// 创建表头
for (const key in data[0]) {
const th = document.createElement('th');
th.textContent = key;
headerRow.appendChild(th);
}
// 创建数据行
data.forEach(rowData => {
const row = tbody.insertRow();
for (const key in rowData) {
const cell = row.insertCell();
cell.textContent = rowData[key];
}
});
return table;
}
// 初始显示
executeSQL();
</script>
</body>
</html>
注意事项与相关技巧
最后,我们来介绍一些处理多个条件时的注意事项,以及一些相关的便捷运算符。
NULL的处理
数据库中存在一个特殊的值NULL。它表示“数据不存在”的空状态。
需要注意的是,NULL不能用=或!=来进行比较。要判断是否为NULL,必须使用专用的IS NULL或IS NOT NULL。
-- 查找工资未设定(为NULL)的员工
SELECT * FROM employees WHERE salary IS NULL;
-- 查找工资已设定(不为NULL)的员工
SELECT * FROM employees WHERE salary IS NOT NULL;
虽然这次的示例数据中没有NULL,但在实际开发中会频繁出现。即使写了WHERE salary = NULL也不会报错,但并不能得到预期的结果,需要注意。
更便捷的条件指定:IN 与 BETWEEN
有时,我们可以把一长串的OR或AND写得更简洁。
IN: OR的替代方案
像“隶属销售部、人事部或会计部”这样,需要对同一个字段用OR连接多个值时,使用IN可以让代码更清爽。
-- 使用多个OR的情况
SELECT * FROM employees
WHERE department = '営業部' OR department = '人事部';
-- 使用IN的简洁写法
SELECT * FROM employees
WHERE department IN ('営業部', '人事部');
BETWEEN: AND的替代方案
当需要指定数值或日期的范围时,例如“工资在400000以上,并且在600000以下”,使用BETWEEN会很方便。
-- 使用AND指定范围的情况
SELECT * FROM employees
WHERE salary >= 400000 AND salary <= 600000;
-- 使用BETWEEN的简洁写法
SELECT * FROM employees
WHERE salary BETWEEN 400000 AND 600000;
当然,这些运算符也可以和AND、OR、NOT组合使用。把它们收入你的技能库,能让你写出更漂亮的SQL。
总结
辛苦了!这次我们通过具体的例子,学习了在SQL中指定多个条件的基础——AND、OR和NOT。
- AND:“A 并且 B”。所有条件都为真时才为真。感觉是缩小范围。
- OR:“A 或者 B”。只要有任一条件为真即为真。感觉是扩大选择。
- NOT:“不是…”。将条件反转。感觉是排除。
- AND与OR的组合:
AND的优先级更高,因此用()明确计算顺序至关重要!
掌握了这些逻辑运算符,即使是复杂的条件你也能随心所欲地提取数据,你的数据操作技能将得到极大的提升。
请活用本次介绍的SQL执行环境等工具,多多尝试各种条件组合。SQL这东西,越写越练,水平越高。希望本文能为你成为SQL大师的道路上助一臂之力!