加入子查询,反模式?

时间:2018-09-24 07:54:32

标签: mysql sql sql-server

我有一个要连接的表A和表B,我只需要几列,所以我认为最好从表a和b创建子查询,然后像下面试图说明的那样将它们联接:

select * from (Select * from (SELECT A,B,C FROM table1 where A =4756937 and B=290) as a
    join
      (SELECT D,E,F FROM table2) as b
      on a.A = b.E )as c
      join
      (SELECT G,H,I,J
      FROM table2) as d
      on c.F = d.H 
    order by A;

原因是

  1. 就像我已经说过的,我只希望有一部分列
  2. 我可能想要一个特殊的数据子集,例如A = 4756937

所以第一个问题将是:这是一种反模式吗?还是数据库系统会优化查询?

第二个问题:其他程序员会如何看待样式?有足够的理由参加SQL课程吗?

最后一个问题:在我已经连接表a&b之后的最后一次连接中,我再次在表d(这也是表b的子查询)上加入了构造,因为我在表b中有重复项。

所以我查询的想法是从表a获取特定的nr并将其加入到键列wihtin表b中,这没什么特别的: enter image description here

但是表b还具有另一个键列(b.f),该键列指示数据行具有类似“小兄弟行”的内容。这就是为什么我加入表b(再次作为子查询)的原因:

enter image description here

再次提出一个问题:我在此用例中所做的工作是否合理且在性能方面明智,还是我陷入了某种反模式?

1 个答案:

答案 0 :(得分:6)

虽然我不会真正将其称为反模式,但我认为将查询部分分开更明智:

  • 结果集
  • 数据集
  • 选择器
  • 排序
  • 在您的情况下不适用:汇总

所以我会考虑类似的东西

SELECT -- Result set definition
  X.A AS A,
  X.B AS B,
  X.C AS C,
  Y.D AS D,
  Y.E AS E,
  Y.F AS F,
  Z.G AS G,
  Z.H AS H,
  Z.I AS I,
  Z.J AS J
FROM -- Dataset definition
  table1 AS X
  INNER JOIN table2 AS Y ON X.A=Y.E
  INNER JOIN table2 AS Z ON Y.F=Z.H
WHERE -- Selector
  X.A=4756937
  AND X.B=290
ORDER BY -- sorting
  X.A
;

为什么这会有优势?

  • 它为查询优化器提供了最大的自由度
  • 它保留所有范围内的所有索引(并非所有RDBMS都可以使用范围外的索引,如果嵌套子查询的大小达到上限,对于MySQL也是如此)
  • 这是最可移植的SQL:也许您想一次使用MySQL以外的东西?
  • 它是可读且可维护的:如果基础表的结构或您的结果集要求发生变化该怎么办?