执行多个SQL查询的最有效方法(子查询与使用JOINS的CTE)

时间:2017-07-19 19:28:56

标签: sql subquery common-table-expression

这是一般SQL练习的抽象问题而非实际实现,因为我相信我知道如何修改每个版本。

所以我有一个实体类型,称之为实体A,我可以通过标准查询检索,类似于这样(这是一个人为的例子,所以语法道歉):

# Query A
SELECT DISTINCT tableName.A
FROM super_duper_long_table_name AS tableName
WHERE tableName.X = "something" and tableName.A IS NOT NULL

但我并不真正关心实体A.我只需要它来到其他我可以根据A轻松查找的实体。我可以用子查询查找每个这些重要实体: / p>

# Query B
SELECT tableName2.B1, tableName2.B2, tableName2.B3
FROM super_duper_long_table_name2 AS tableName2
WHERE tableName2.A IN
(
# Query A, same as above
)
GROUP BY tableName2.B1, tableName2.B2, tableName2.B3

所以我的问题是,做几个版本的查询B(可能是3个)来更好地使用相同的子查询多次获取重要的实体(如果我改变它,我将不得不更新多个)或者,对于我想要的每个重要实体,使用JOINS进行CTE并将其形成一个怪物查询是否更好?

或者甚至,故意将它们分开是否更好,因此调用查询A,将结果保存在临时var中,然后将枚举实体提供给每个查询B版本的WHERE子句?

很抱歉,如果这太模糊并且开始讨论太多,但我并不是非常熟悉SQL的最佳实践,所以这似乎是一个好的开始。谢谢!

2 个答案:

答案 0 :(得分:2)

对queryA使用CTE(或临时表),然后在以后的所有查询中使用JOIN来自/ {/ p>

; WITH QueryA AS (
SELECT DISTINCT tableName.A
FROM super_duper_long_table_name AS tableName
WHERE tableName.X = "something" and tableName.A IS NOT NULL)

SELECT tableName2.B1, tableName2.B2, tableName2.B3
FROM QueryA AS A
JOIN super_duper_long_table_name2 AS tableName2 ON tableName2.A = QueryA.A

这样,您将只对查询A进行一次过滤逻辑。如果在查询B的每个版本中对它进行子查询,那么当您不需要时,您将浪费大量时间重新处理查询A.

答案 1 :(得分:1)

请记住,group by用于聚合功能,而不是一种假的不同的clase ..无论如何,suuld会更好 内连接而不是IN子句

在主要选择的JOIN中使用select表在SQL中是典型的。(或CTE)本质上结果是共同元素的交互

  SELECT tableName2.B1, tableName2.B2, tableName2.B3
  FROM super_duper_long_table_name2 AS tableName2
  INNER JOIN (
      SELECT DISTINCT tableName.A as TA
      FROM super_duper_long_table_name AS tableName
      WHERE tableName.X = "something" and tableName.A IS NOT NULL
  ) T ON tableName2.A  = T.TA

在sql中不推荐使用group by without aggregation函数,并且不允许使用大多数db版本