sql - 理解复杂 SQL 语句的最佳方式?

标签 sql database

有没有人有办法理解复杂的 SQL 语句?在阅读结构化/面向对象代码时,通常有抽象层可以帮助您将其分解为可管理的块。但是,通常在 SQL 中,您似乎必须同时跟踪查询的多个部分中发生的情况。

这个问题的插入力是在this question about a complex join中讨论的SQL查询。 .在盯着答案查询几分钟后,我最终决定使用特定记录单步执行查询以查看发生了什么。这是我能想到的逐条理解查询的唯一方法。

有没有更好的方法将 SQL 查询分解为可管理的部分?

最佳答案

当我查看一些复杂的 SQL 代码时,这就是我所做的。

首先,如果它是更新或删除,我添加代码(如果它不存在并注释掉)以使其成为选择。第一次尝试更新或删除时,请先不要在选择中看到结果。如果是更新,我确保选择显示当前值以及我将设置的值,以确保获得所需的结果。

了解联接对于了解复杂的 SQL 至关重要。对于每一次加入,我都会问自己为什么会在这里?有四个基本原因。您需要一个用于选择的列,您需要一个用于 where 子句的字段,您需要连接作为到第三个表的桥梁,或者您需要连接到该表以过滤记录(例如检索有关有订单的客户的详细信息但不需要订单详细信息,这通常可以使用 IF EXISTS where 子句更好地完成)。如果是左连接或右连接(我倾向于重写,所以一切都是左连接,这使生活更简单。),我会考虑内部连接是否可行。为什么需要左连接?如果我不知道答案,我会以两种方式运行它并查看数据中的差异。如果有派生表,我将首先查看那些(只运行 select 的那部分以查看结果)以了解它为什么存在。如果有子查询,我会尝试理解它们,如果它们很慢,我会尝试转换为派生表,因为它们通常要快得多。

接下来看where条款。这是您的特定数据库中的坚实基础将派上用场的地方。例如,我知道在我的数据库中什么情况下我可能只需要查看邮寄地址,什么情况下我可能需要查看其他地址。这有助于我知道 where 子句中是否缺少某些内容。否则我会考虑 where 中的每个项目条款并弄清楚为什么它需要在那里,然后我考虑是否有任何应该存在的缺失。在查看之后,我考虑是否可以进行调整以使查询可以进行查询。

接下来我还会考虑选择列表的任何复杂位。这个case语句有什么作用?为什么会有子查询?这些函数有什么作用? (我总是查找任何我不熟悉的函数的函数代码。)为什么会有一个不同的?可以通过使用派生表或聚合函数和 group by 语句来摆脱它吗?

最后也是最重要的 ,我运行选择并根据我对业务的了解确定结果是否正确。如果您不了解您的业务,您就不会知道查询是否正确。语法正确并不意味着正确的结果。通常,您可以将现有用户界面的一部分用作您的结果是否正确的指南。如果我有一个显示客户订单的屏幕,并且我正在做一个包含客户订单的报告,我可能会抽查一些个别客户以确保它显示正确的结果。

如果当前查询过滤不正确,我将删除它的一部分以找出是什么摆脱了我不想要的记录或添加了我不想要的记录。通常,您会发现连接是一对多的并且您需要一对一(在这种情况下使用派生表!)或者您会在 where 中找到您认为需要的一些信息。条款不适用于您需要的所有数据或 where 的某些部分缺少条款。拥有 where 中的所有字段会有所帮助。执行此操作时选择中的子句(如果它们不在选择中)。它甚至可能有助于显示所有连接表中的所有字段并真正查看数据。当我这样做时,我经常在 where 子句中添加一点,以获取我拥有的一些不应该存在的记录,而不是所有记录。

一个会破坏很多查询的偷偷摸摸的东西是 where子句引用左联接右侧表中的字段。这把它变成了一个内部连接。如果你真的需要一个左连接,你应该将这些条件添加到连接本身。

关于sql - 理解复杂 SQL 语句的最佳方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/379062/

相关文章:

mysql - 如何从 MySQL Workbench 中的图表生成 SQL 脚本?

mysql - sql 根据最新价格求和

sql - 从 DB2 存储过程中检索返回值

asp.net - T-SQL 检查重复的 field1 值但不同的 field2 值

mysql - 将 JSON_EXTRACT 与 CAST 或 STR_TO_DATE 链接失败

database - greenplum分区优化

ruby-on-rails - 用于多态的 _type 列是什么?

运行 INSERT 时 PHP mysql 错误

php - 使用 php 在从数据库检索的表中添加按钮

mysql - 我可以对 2 个数据库执行单个查询吗?