当前位置:  开发笔记 > 数据库 > 正文

理解复杂SQL语句的最佳方法是什么?

如何解决《理解复杂SQL语句的最佳方法是什么?》经验,为你挑选了6个好方法。

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

此问题的推动力是此问题中讨论的关于复杂连接的SQL查询.在盯着答案查询几分钟后,我终于决定使用特定记录逐步查询查看发生了什么.这是我能想到的唯一方法来逐一理解查询.

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



1> HLGEM..:

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

首先,如果是更新或删除,我添加代码(如果它不存在并注释掉)以使其成为选择.切勿首次尝试更新或删除,而不先在选择中查看结果.如果是更新,我确保选择显示当前值以及我将其设置为什么,以确保我得到所需的结果.

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

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

我还考虑下一个选择列表的任何复杂位.那个案例陈述做了什么?为什么有子查询?这些功能有什么作用?(我总是查找我不熟悉的任何函数的函数代码.)为什么有明显的?是否可以通过使用派生表或聚合函数和group by语句来消除它?

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

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

一个会破坏大量查询的偷偷摸摸的东西是where引用左连接右侧表格中的字段的子句.这将它变成了一个内部联接.如果您确实需要左连接,则应将这些条件添加到连接本身.



2> Kon..:

这些可能是一些有用的提示..

评论 - 弄清楚一个小块的作用并对其进行评论,以便您在以后再参考它时理解它.

语法突出显示 - 确保您正在查看带有对查询进行颜色编码的代码.

缩进 - 重新组织查询以使您有意义..选项卡结束,添加回车符.

例如:

select ID, Description, Status from ABC where Status = 1 OR Status = 3

可以更好地写为:

select 
  ID,
  Description,
  Status
from ABC
where
  Status = 1 OR
  Status = 3

通过更复杂的查询,您将看到更大的好处.



3> John MacInty..:

这是解开查询的过程.

    首先我格式化SQL.

    然后我注释掉SQL的所有部分,而不是最主要或最重要的表的基本部分来回答问题.

    然后我将开始取消注释连接,选择列,分组,顺序字段和过滤器以分析查询的不同部分以查看发生的情况.或突出显示 - 执行在某些工具中有效.

    子查询通常可以独立执行.

执行这些中的每一个通常可以让我更好地掌握查询中发生的事情.



4> Stephane Gre..:

大多数情况下,这只是经验和适当的缩进.



5> EvilTeach..:

缩进和评论有很多帮助.我遇到的最有价值的事情是WITH语句.它在Oracle中,处理子查询重构.它允许您将大型查询分解为一组看似较小的查询.每个只是更易于管理.

这是一个例子

WITH 
ssnInfo AS
(
    SELECT SSN, 
           UPPER(LAST_NAME), 
           UPPER(FIRST_NAME), 
           TAXABLE_INCOME,          
           CHARITABLE_DONATIONS
    FROM IRS_MASTER_FILE
    WHERE STATE = 'MN'                 AND -- limit to in-state
          TAXABLE_INCOME > 250000      AND -- is rich 
          CHARITABLE_DONATIONS > 5000      -- might donate too

),
doltishApplicants AS
(
    SELECT SSN, 
           SAT_SCORE,
           SUBMISSION_DATE
    FROM COLLEGE_ADMISSIONS
    WHERE SAT_SCORE < 100          -- About as smart as a Moose.
),
todaysAdmissions AS
(
    SELECT doltishApplicants.SSN, 
           TRUNC(SUBMISSION_DATE)  SUBMIT_DATE, 
           LAST_NAME, FIRST_NAME, 
           TAXABLE_INCOME
    FROM ssnInfo,
         doltishApplicants
    WHERE ssnInfo.SSN = doltishApplicants.SSN

)
SELECT 'Dear ' || FIRST_NAME || 
       ' your admission to WhatsaMattaU has been accepted.'
FROM todaysAdmissions
WHERE SUBMIT_DATE = TRUNC(SYSDATE)    -- For stuff received today only
;

使用内联视图可以完成同样的操作,但是还可以在需要时创建临时表.在某些情况下,您可以复制出子查询并在大型查询的上下文之外执行它.

此表单还允许您将过滤器子句与单个子查询放在一起,并保存最终选择的连接子句.

在工作中,我们的开发小组通常发现它们更容易维护,而且通常更快.



6> Steven A. Lo..:

格式化有所帮助,但理解集合论和扩展,关系理论,甚至更有帮助.

对查询执行方式的模糊理解也不会造成影响(表扫描,索引扫描,索引跳转,哈希表合并等); 查询计划程序可以向您显示这些操作

一些操作(有,存在,有)一开始可能很麻烦

首先要了解每个表发生了什么,以及如何连接表

推荐阅读
ifx0448363
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有