🇯🇵 日本語 | 🇺🇸 English | 🇪🇸 Español | 🇵🇹 Português | 🇹🇭 ไทย | 🇨🇳 中文

【SQL入门】成为多条件达人!完全掌握 AND, OR, NOT

“想从数据库里提取特定的数据,但一个条件不够用…”
作为一名Web开发者,在职业进阶的道路上,你是否也曾遇到过这样的瓶颈?

SQL是操作数据库的语言,其中用于提取数据的SELECT语句是基础中的基础。但是,要精准地获取到你真正想要的信息,组合多个条件来筛选数据的技巧是必不可少的。

本文将为你彻底解说用于指定多个条件的三个逻辑运算符——ANDORNOT的用法,并附上即使是初学者也能直接复制粘贴运行的示例代码!希望通过“代码成功运行”的体验,让你感受到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;
    

这个结果里包含了:

伊藤先生和中村女士同时满足两个条件,当然也会被包含在结果里。OR是一个比较宽松的条件指定,意思是“只要满足至少一个条件就OK”。


3. NOT:提取不符合条件的数据!

NOT顾名思义,就是用来指定“不是…”这样的否定条件。在希望排除掉拥有特定条件的数据时非常方便。

基本用法

WHERE子句中,把它放在你想要否定的条件前面。

举个例子,我们来获取所有在“开发部”的员工。


SELECT *
FROM employees
WHERE NOT department = '開発部';
    

执行这个查询,所有除了'开发部'的员工,也就是'営業部'(销售部)和'人事部'(人事部)的员工,都会被显示出来。
顺便一提,写成WHERE department != '開発部'WHERE department <> '開発部'也能得到同样的结果。具体使用哪个取决于个人喜好或团队规范,但NOT的特点是能够和INEXISTS等其他运算符组合使用,表达范围更广。


【进阶篇】AND与OR的组合及“括号”的重要性

好了,从这里开始是重头戏!通过组合ANDOR,我们可以指定更复杂的条件。但是,这里有一个初学者很容易掉进去的大坑,那就是运算符的优先级

在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 NULLIS 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

有时,我们可以把一长串的ORAND写得更简洁。

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;
    

当然,这些运算符也可以和ANDORNOT组合使用。把它们收入你的技能库,能让你写出更漂亮的SQL。


总结

辛苦了!这次我们通过具体的例子,学习了在SQL中指定多个条件的基础——ANDORNOT

掌握了这些逻辑运算符,即使是复杂的条件你也能随心所欲地提取数据,你的数据操作技能将得到极大的提升。

请活用本次介绍的SQL执行环境等工具,多多尝试各种条件组合。SQL这东西,越写越练,水平越高。希望本文能为你成为SQL大师的道路上助一臂之力!