每个初学者都会犯的 7 个 SQL 错误(以及如何纠正它们)

每个初学者都会犯的 7 个 SQL 错误(以及如何纠正它们)

我还记得第一次 SQL 查询返回零结果时的情景。我检查了表格,核对了列名,并重新阅读了三次查询。一切看起来都很完美。但数据库却不同意,我也不知道为什么。

原来,我写的是WHERE manager_id = NULL,而不是WHERE manager_id IS NULL。一个小字让我花费了一个小时的调试时间。

如果你正在学习 SQL,可能也会遇到类似的挫折。好消息是什么?你犯了每个初学者都会犯的错误。好消息呢?只要你知道要注意什么,这些错误就很容易解决。

在本指南中,我将带你了解绊倒初学者的 7 个最常见的 SQL 错误、它们发生的原因,以及准确的修正方法。最后,你将避免数小时的挠头调试,从第一天起就能编写出更简洁、更可靠的查询。


错误 1:使用= NULL代替IS NULL

问题所在

这是初学者最容易犯的错误,而且非常简单。当你想查找缺失值或未定义值的记录时,你的第一反应可能是编写查询:

sql 复制代码
SELECT * FROM employees
WHERE manager_id = NULL;

该查询运行时不会出错,但即使表中存在 NULL 值,也总是返回零结果。为什么会这样?因为在 SQL 中,NULL代表 "未知",而且无法使用等式来比较未知值。

解决方法

始终使用ISNULL 检查 NULL 值:

sql 复制代码
SELECT * FROM employees
WHERE manager_id IS NULL;

使用IS NOT NULL查找有值的行:

sql 复制代码
SELECT * FROM employees
WHERE email IS NOT NULL;

**专业提示:**记住,NULL = NULL返回NULL(而不是 TRUE),在 WHERE 子句中被视为 FALSE。NULL 不等于任何东西,甚至不等于它本身。


错误 2:忘记给字符串加上引号

问题所在

另一个常见的绊脚石是:忘记用引号将文本值包住。你可能会写

sql 复制代码
SELECT * FROM products
WHERE category = Electronics;

这会产生错误,因为 SQL 认为Electronics是列名,而不是文本值。数据库会查找一个不存在的名为 "Electronics "的列。

解决方法

始终用单引号括起字符串字面量:

sql 复制代码
SELECT * FROM products
WHERE category = 'Electronics';

数字不需要引号:

sql 复制代码
WHERE price > 100    -- Correct (number)
WHERE status = 'active'    -- Correct (string)

**常见陷阱:**不要对字符串使用双引号--在标准 SQL 中,双引号用于标识符(表/列名),而不是值。


错误 3:混淆 AND/OR 逻辑而不使用括号

问题所在

在组合多个条件时,初学者通常会写出这样的查询:

sql 复制代码
SELECT * FROM products
WHERE category = 'Electronics'
   OR category = 'Computers'
  AND price < 500;

您可能希望返回所有低于 500 美元的电子产品和计算机。但由于AND 的优先级高于OR,SQL 会将其读作

"获取所有电子产品(任何价格)或(500 美元以下的计算机)"

这会返回你不想要的昂贵的电子产品。

解决方法

始终使用括号来清楚地表明你的意图:

sql 复制代码
SELECT * FROM products
WHERE (category = 'Electronics' OR category = 'Computers')
  AND price < 500;

现在,两个类别都必须低于 500 美元,这正是您想要的。

**经验法则:**无论何时混合AND 和 OR,都要使用小括号--即使你了解优先级。这样可以防止出错,并使查询具有可读性。


错误 4:在生产代码中使用SELECT *

问题所在

在探索数据时,键入SELECT *非常方便--它可以显示所有内容:

sql 复制代码
SELECT * FROM customers;

但在生产代码中,这却是性能杀手。你在检索不需要的列,浪费内存和网络带宽。更糟糕的是,如果以后有人向表中添加列,你的应用程序就会突然收到无法处理的额外数据。

解决方法

只明确列出需要的列:

sql 复制代码
SELECT customer_id, first_name, email
FROM customers;

优点

  • 查询执行速度更快
  • 降低内存使用率
  • 代码自文档化(准确显示使用的内容)
  • 面向未来,防止表模式发生变化

**何时使用 SELECT *?**仅用于快速数据探索或测试,切勿在应用代码中使用。


错误 5:使用 LIMIT 而不使用 ORDER BY

问题所在

您想查看一些示例记录,所以您写道:

sql 复制代码
SELECT * FROM orders
LIMIT 10;

这看起来不错,但如果不使用ORDER BY,就会得到随机记录。运行两次,你可能会看到不同的结果。这样就无法进行调试,而且会产生不一致的应用程序行为。

修复方法

使用LIMIT 时,始终添加ORDER BY

sql 复制代码
SELECT * FROM orders
ORDER BY order_date DESC
LIMIT 10;

现在你可以持续获得 10 个最新订单。

使用案例:

  • 前 N 个查询:"获取 5 名薪资最高的员工
  • 分页:"显示产品的第 2 页
  • 最近的项目"显示最新的 20 篇文章

错误 6:在计算中忽略 NULL

问题所在

您是这样计算折扣价的:

sql 复制代码
SELECT 
    product_name,
    price,
    discount,
    price - discount AS sale_price
FROM products;

在遇到折扣为 NULL 的产品之前,计算都很顺利。整个计算返回 NULL,因为对 NULL 进行任何算术运算都会产生 NULL。

因此100 - NULL = NULL,而不是 100。

修复方法

使用COALESCE()为 NULL 提供默认值:

sql 复制代码
SELECT 
    product_name,
    price,
    discount,
    price - COALESCE(discount, 0) AS sale_price
FROM products;

如果存在折扣,COALESCE(discount, 0)将返回折扣;如果为 NULL则返回 0。

其他常见情况:

  • total_sales / COALESCE(order_count,1)(避免除以零)
  • COALESCE(middle_name,'')(将 NULL 转换为空字符串)

错误 7:试图在 WHERE 中使用列别名

问题所在

您创建了一个计算列,并尝试用它进行筛选:

sql 复制代码
SELECT 
    product_name,
    price * 1.1 AS price_with_tax
FROM products
WHERE price_with_tax > 100;

错误!SQL 说price_with_tax不存在。这让初学者感到困惑,因为别名就在 SELECT 中。

解决方法

SQL 按特定顺序评估子句:WHERE运行在SELECT 之前,因此当过滤发生时,别名还不存在。

在 WHERE 中重复计算:

sql 复制代码
SELECT 
    product_name,
    price * 1.1 AS price_with_tax
FROM products
WHERE price * 1.1 > 100;

**好消息:**您可以在ORDER BY中使用别名,因为它在 SELECT 之后运行:

sql 复制代码
SELECT 
    salary * 12 AS annual_salary
FROM employees
ORDER BY annual_salary DESC;    -- This works!

结论:从第一天起就编写更好的 SQL

在初学者花费在 SQL 上的调试时间中,这七个错误可能占了 80%。好消息是什么?现在你知道了它们,就能避免数小时的挫败感。

快速回顾:

  • 使用IS NULL,绝不= NULL
  • 用单引号包住字符串
  • 在 AND/OR 逻辑中使用小括号
  • 避免在生产中使用SELECT *
  • 始终将 LIMIT 与 ORDER BY 搭配使用
  • 在计算中处理 NULL 值
  • 不要在 WHERE 中引用别名

掌握 SQL 的秘诀不是死记硬背语法,而是了解这些常见陷阱以及如何避免它们。在练习时,请随身携带本指南,这样从第一天起,你就能编写出更简洁、更可靠的查询。

**下一步:**试着针对每个错误编写 10 个练习查询。练习得越多,这些模式就会成为你的第二天性。


实践练习

尝试修正这个查询--它包含本文中的 3 个错误:

sql 复制代码
SELECT * FROM employees
WHERE department = Sales
   OR salary > 50000
  AND manager_id = NULL
LIMIT 5;

答案:

  1. 缺少引号:销售
  2. 缺少括号:(部门 = '销售' 或工资 > 50000)
  3. 错误的 NULL 检查:IS NULL
  4. 奖励:将ORDER BY添加为 LIMIT

你都找到了吗?

相关推荐
不剪发的Tony老师4 小时前
Yearning:一个免费开源的SQL审核平台
数据库·sql·mysql
Gauss松鼠会4 小时前
GaussDB慢sql信息收集和执行计划查看
数据库·sql·gaussdb
呼哧呼哧.17 小时前
Spring的核心思想与注解
数据库·sql·spring
嘗_18 小时前
sql特训
数据库·sql
橙汁味的风20 小时前
3关系型数据库的SQL语言
数据库·sql
蹦跶的小羊羔1 天前
sql数据库语法
数据库·sql
PawSQL1 天前
企业级SQL审核工具PawSQL介绍(1) - 六大核心能力
数据库·sql·oracle
唐古乌梁海1 天前
【python】在Django中,执行原生SQL查询
python·sql·django
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ1 天前
mapper.xml sql动态表查询配置
xml·java·sql