Skip to content

MySQL - AND 运算符

AND 运算符是 MySQL 中用于在查询中组合多个条件的基本逻辑运算符。它允许您以高精度过滤数据,确保满足所有指定的条件。

AND 运算符组合两个或多个布尔表达式。在 MySQL 中,如果表达式计算结果为非零、非 NULL 的数字,则视为 true;如果计算结果为 0,则视为 false。AND 运算符根据以下规则返回结果:

  • 仅当它连接的所有表达式都为 true 时,才返回 true (1)。
  • 如果至少一个表达式为 false,则返回 false (0)。
  • 如果所有表达式都不为 false,但至少有一个为 NULL,则返回 NULL。

下表总结了 AND 运算符的行为:

ABA AND B
TRUETRUETRUE (1)
TRUEFALSEFALSE (0)
FALSETRUEFALSE (0)
FALSEFALSEFALSE (0)
TRUENULLNULL
FALSENULLFALSE (0)
NULLNULLNULL

您可以直接使用 SELECT 语句测试 AND 运算符。

-- 两者都为 true,所以结果是 1 (true)
SELECT 1 AND 1; -- Result: 1
-- 其中一个为 false,所以结果是 0 (false)
SELECT 1 AND 0; -- Result: 0
-- 其中一个为 NULL,另一个为 true,所以结果是 NULL
SELECT 1 AND NULL; -- Result: NULL
-- 其中一个为 NULL,但另一个为 false,所以结果是 0 (false)
SELECT 0 AND NULL; -- Result: 0

AND 运算符最常见的用途是在 SELECT 语句的 WHERE 子句中过滤表中的行。只有当一行满足 AND 连接的所有条件时,它才会被包含在结果集中。

SELECT column1, column2, ...
FROM table_name
WHERE condition1 AND condition2 AND ...;

首先,让我们为示例设置一个 CUSTOMERS 表。

CREATE TABLE CUSTOMERS(
ID INT AUTO_INCREMENT PRIMARY KEY,
NAME VARCHAR(20) NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(25),
SALARY DECIMAL(18, 2)
);
INSERT INTO CUSTOMERS(NAME, AGE, ADDRESS, SALARY) VALUES
('Ramesh', 32, 'Ahmedabad', 2000.00),
('Khilan', 25, 'Delhi', 1500.00),
('Kaushik', 23, 'Kota', 2000.00),
('Chaitali', 25, 'Mumbai', 6500.00),
('Hardik', 27, 'Bhopal', 8500.00),
('Komal', 22, 'Hyderabad', 4500.00),
('Muffy', 24, 'Indore', 10000.00);

现在,让我们找出所有 25 岁并且住在**“Mumbai”**的客户。

SELECT ID, NAME, AGE, ADDRESS, SALARY
FROM CUSTOMERS
WHERE AGE = 25 AND ADDRESS = 'Mumbai';

只有一条记录同时满足这两个条件:

IDNAMEAGEADDRESSSALARY
4Chaitali25Mumbai6500.00

在 MySQL 中,AND 的优先级高于 OR。这意味着 AND 条件在 OR 条件之前进行评估。为避免歧义并确保逻辑正确,最佳实践是在混合使用 AND 和 OR 运算符时使用括号 ()。

-- 这会找到 25 岁且住在孟买的客户,或者任何薪水超过 8000 的客户
SELECT NAME, AGE, ADDRESS, SALARY
FROM CUSTOMERS
WHERE (AGE = 25 AND ADDRESS = 'Mumbai') OR SALARY > 8000;
-- 这不同!它会找到 25 岁,并且(来自孟买或薪水超过 8000)的客户
SELECT NAME, AGE, ADDRESS, SALARY
FROM CUSTOMERS
WHERE AGE = 25 AND (ADDRESS = 'Mumbai' OR SALARY > 8000);

AND 运算符对于执行精确的数据修改也至关重要,它确保您只更新或删除您想要操作的精确记录。

让我们为居住在“Hyderabad”名叫“Komal”的客户增加工资。

UPDATE CUSTOMERS
SET SALARY = 5000.00
WHERE NAME = 'Komal' AND ADDRESS = 'Hyderabad';

运行此查询后,只有 Komal 的记录会被更新。这种精确性可以防止意外更新其他可能也叫“Komal”但住在其他地方的客户。

现在,让我们删除住在“Delhi”名叫“Khilan”的客户。

DELETE FROM CUSTOMERS
WHERE NAME = 'Khilan' AND ADDRESS = 'Delhi';

安全警告: UPDATE 和 DELETE 语句务必始终与 WHERE 子句一起使用。忘记使用它将导致操作应用于表中的所有行。使用 AND 创建高度特定的条件是关键的安全实践。

在应用程序代码中使用 AND 运算符

Section titled “在应用程序代码中使用 AND 运算符”

在构建应用程序时,您会经常构建包含多个条件的查询。使用预处理语句(或参数化查询)来防止 SQL 注入攻击至关重要。这种方法将 SQL 命令与数据分离,将用户输入视为值而非可执行代码。

以下示例展示了如何使用现代最佳实践和预处理语句,安全地执行带有 AND 运算符的 SELECT 查询。请记住使用环境变量安全地存储凭证。

Node.js
Python
Java
PHP
此示例使用 `mysql2/promise` 并将用户提供的值作为数组传递给 `execute` 方法。
```javascript
const mysql = require('mysql2/promise');
require('dotenv').config();
const pool = mysql.createPool({ /* ... 连接配置 ... */ });
async function findCustomers(age, address) {
let connection;
try {
connection = await pool.getConnection();
const sql = "SELECT ID, NAME, AGE FROM CUSTOMERS WHERE AGE = ? AND ADDRESS = ?;";
// `?` 是占位符。数组安全地提供了值。
const [rows] = await connection.execute(sql, [age, address]);
if (rows.length > 0) {
console.log(`找到 ${rows.length} 个符合条件的客户:`)
console.table(rows);
} else {
console.log("未找到符合条件的客户。");
}
} catch (error) {
console.error("查询失败:", error);
} finally {
if (connection) connection.release(); // 释放连接回连接池
}
}
// Example usage
findCustomers(25, 'Mumbai');

此 Python 示例使用 mysql-connector-python。execute 方法接受一个参数元组,以安全地将它们绑定到查询中的占位符。

import mysql.connector
import os
from dotenv import load_dotenv
load_dotenv()
def find_customers(age, address):
try:
with mysql.connector.connect(
host=os.getenv("DB_HOST"),
user=os.getenv("DB_USER"),
password=os.getenv("DB_PASSWORD"),
database=os.getenv("DB_NAME")
) as connection:
sql = "SELECT ID, NAME, AGE FROM CUSTOMERS WHERE AGE = %s AND ADDRESS = %s"
params = (age, address)
with connection.cursor(dictionary=True) as cursor:
cursor.execute(sql, params)
results = cursor.fetchall()
if results:
print(f"找到 {len(results)} 个客户:");
for row in results:
print(f"- ID: {row['ID']}, Name: {row['NAME']}, Age: {row['AGE']}")
else:
print("未找到客户。")
except mysql.connector.Error as e:
print(f"数据库错误:{e}")
# Example usage
findCustomers(25, 'Mumbai')

此 Java 示例使用 PreparedStatement,这是 JDBC 中执行参数化查询的标准方式。set... 方法用于将值绑定到 ? 占位符。

import java.sql.*;
public class FindCustomers {
public static void find(int age, String address) {
String url = "jdbc:mysql://" + System.getenv("DB_HOST") + "/" + System.getenv("DB_NAME");
String user = System.getenv("DB_USER");
String password = System.getenv("DB_PASSWORD");
String sql = "SELECT ID, NAME, AGE FROM CUSTOMERS WHERE AGE = ? AND ADDRESS = ?";
try (Connection conn = DriverManager.getConnection(url, user, password);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, age); // 将第一个 `?` 绑定到 `age` 变量
pstmt.setString(2, address); // 将第二个 `?` 绑定到 `address` 变量
try (ResultSet rs = pstmt.executeQuery()) {
if (!rs.isBeforeFirst()) {
System.out.println("未找到客户。");
return;
}
while (rs.next()) {
System.out.printf("ID: %d, Name: %s, Age: %d\n",
rs.getInt("ID"),
rs.getString("NAME"),
rs.getInt("AGE"));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
find(25, "Mumbai");
}
}

此 PHP 示例使用 mysqli 和预处理语句。查询中使用占位符 ?,bind_param 用于安全地附加变量。

<?php
require_once __DIR__ . '/vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli($_ENV['DB_HOST'], $_ENV['DB_USER'], $_ENV['DB_PASSWORD'], $_ENV['DB_NAME']);
function findCustomers($mysqli, $age, $address) {
$sql = "SELECT ID, NAME, AGE FROM CUSTOMERS WHERE AGE = ? AND ADDRESS = ?";
try {
$stmt = $mysqli->prepare($sql);
// 'is' 表示 integer(整数)、string(字符串)。这告诉 MySQL 参数的数据类型。
$stmt->bind_param('is', $age, $address);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows > 0) {
echo "找到客户:\n";
while ($row = $result->fetch_assoc()) {
printf("- ID: %d, Name: %s, Age: %d\n", $row['ID'], $row['NAME'], $row['AGE']);
}
} else {
echo "未找到客户。\n";
}
$stmt->close();
} catch (mysqli_sql_exception $e) {
echo "错误:" . $e->getMessage() . "\n";
}
}
// Example usage
findCustomers($mysqli, 25, 'Mumbai');
$mysqli->close();
?>