简体   繁体   English

嵌套语句和CTE的查询设计

[英]Query design for nested statements and CTEs

I have a query that sequentially joins 6 tables from their original data sources. 我有一个查询,该查询从其原始数据源开始顺序连接6个表。 Nested, it's a mess: 嵌套,一团糟:

SELECT
FROM
(
    SELECT
    FROM
    (
        SELECT
        FROM
        (. . .)
        INNER JOIN
    )
    INNER JOIN
)

I switched to CTE definitions, and each definition is one join on a previous definition, with the final query at the end providing the result: 我切换到CTE定义,每个定义都是在先前定义上的一个连接,最后的最终查询提供了结果:

WITH
Table1 (field1, field2) AS
(
    SELECT
    FROM 
    INNER JOIN
),

Table2 (field2, field3) AS
(
    SELECT
    FROM Table1
    INNER JOIN
), . . . 

SELECT 
FROM Table 6

This is a lot more readable, and dependencies flow downward in logical order. 这更具可读性,并且依存关系按逻辑顺序向下流动。 However, this doesn't seem like the intended use of CTEs (and also why I'm not using Views), since each definition is really only referenced once in order. 但是,这似乎不像CTE的预期用途(这也是为什么我不使用Views的原因),因为每个定义实际上仅按顺序引用一次。

Is there any guidance out there on how to construct sequentially nested joins like this that is both readable and logical in structure? 关于如何构造顺序可读且结构合理的嵌套连接,是否有任何指南?

I don't think there is anything wrong in utilizing CTE to create temporary views. 我认为利用CTE创建临时视图没有任何问题。

  1. In a larger shop, there are roles defined that separates the responsibility of DBAs versus developers. 在较大的商店中,定义了将DBA和开发人员的责任分开的角色。 The CREATE statement, in general, will be the victim of this bureaucracy. 通常,CREATE语句将成为此官僚机构的受害者。 Hence, no view. 因此,没有观点。 CTE is a very good compromise. CTE是一个很好的折衷方案。
  2. If the views are not really reusable anyway, keeping it with the SQL makes it more readable. 如果无论如何这些视图都不是真正可重用的,则将其与SQL保持在一起将使其更具可读性。
  3. CTE is a lot more readable and intuitive than sub-queries (even with just one level). CTE比子查询(即使只有一个级别)也更具可读性和直观性。 If your subqueries are not correlated, I would just suggesting converting all of your sub-queries to CTE. 如果您的子查询不相关,我建议您将所有子查询转换为CTE。
  4. Recursion is the "killer" app for CTE, but it doesn't mean that you shouldn't use CTE, otherwise. 递归是CTE的“杀手级”应用程序,但这并不意味着您不应该使用CTE。

The only con that I can think of is that (depending on your Database Engine) it might confuse or prevent the optimizer from doing what it's suppose to do. 我能想到的唯一弊端是(取决于您的数据库引擎)它可能会混淆或阻止优化器执行应做的事情。 Optimizers are smart enough to rewrite subqueries for you. 优化器足够聪明,可以为您重写子查询。

Now, let us discuss abuse of CTE, be careful that you don't substitute your application developer knowledge for Database Engine optimization. 现在,让我们讨论CTE的滥用问题,请注意不要将应用程序开发人员的知识替换为数据库引擎优化。 There are a lot of smart developers (smarter that us) that designed this software, just write the query without cte or subqueries as much as possible and let the DB do the work. 设计此软件的有很多聪明的开发人员(我们更聪明),只需编写不带cte或子查询的查询,并尽可能让DB完成工作。 For example, I often see developers DISTINCT/WHERE every key in a subquery before doing their join. 例如,我经常看到开发人员在进行联接之前将DISTINCT / WHERE放在子查询中的每个键上。 You may think your doing the right thing, but you're not. 您可能认为自己做对了,但事实并非如此。

With regards to your question, most people intend to solve problems and not discuss something theoretical. 关于您的问题,大多数人都打算解决问题,而不是在理论上进行讨论。 Hence, you get people scratching their heads on what you are after. 因此,您会让人们为所追求的东西挠头。 I wouldn't say you didn't imply that in your text, but perhaps be more forceful. 我不会说您不是在您的文字中暗示这一点,但也许会更有力。

May be I didn't understand the question but what's wrong with: 可能是我听不懂问题,但出了什么问题:

select * from table1 t1, table2 t2, table3 t3, table4 t4, table5 t5, table6 t6 
where t1.id = t2.id and t2.id = t3.id and  t3.id = t4.id 
  and t4.id = t5.id and t5.id = t6.id

or same using table 1 t1 INNER JOIN table2 t2 ON t1.id = t2.id .... 或使用table 1 t1 INNER JOIN table2 t2 ON t1.id = t2.id ....

why didn't you just join your tables like this 你为什么不只是像这样加入你的桌子

select *
from Table1 as t1
    inner join Table2 as t2 on t2.<column> = t1.<column>
    inner join Table3 as t3 on t3.<column> = t2.<column>
    inner join Table4 as t4 on t4.<column> = t3.<column>
    inner join Table5 as t5 on t5.<column> = t4.<column>
    inner join Table6 as t6 on t6.<column> = t5.<column>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM