SELECT后面的子查询无法删除?

时间:2017-11-02 21:16:36

标签: sql sql-server

相关子查询被认为是bad habit。我相信任何带有SELECTFROM之间子查询的SQL命令(让我们称之为 SELECT子查询)都可以在没有任何内容的情况下重写到SQL中。例如像这样的查询

select *,
(
  select sum(t2.sales)
  from your_table t2
  where t2.dates
         between t1.dates - interval '3' day and 
                 t1.dates and 
       t2.id = t1.id
) running_sales
from your_table t1

demo

可以改写成下面的

 select dd.id, dd.dates, dd.sales, sum(d.sales) running_sales
 from your_table dd
 join your_table d on d.dates
     between (dd.dates - interval '3' day) and 
              dd.dates and 
     dd.id = d.id
 group by dd.id, dd.dates, dd.sales

demo

当存在多个SELECT子查询时可能会出现问题,但是,即使在这种情况下,也可以将它们重写为FROM后面的子查询,然后在下面执行LEFT JOIN精神

select *,
(
  select sum(sales)
  from dat dd
  where dd.dates
         between (d.dates - interval '3' day) and d.dates and 
         dd.id = d.id
) running_sales,
(
  select sum(sales)
  from dat dd
  where dd.id = d.id
) total_sales
from dat d

demo

可以改写成下面的

select d.*,
   t_running.running_sales,
   t_total.total_sales
from dat d
left join (
  select dd.id, dd.dates, sum(d.sales) running_sales
  from dat dd
  join dat d on d.dates
          between (dd.dates - interval '3' day) and 
                   dd.dates and 
          dd.id = d.id
  group by dd.id, dd.dates
) t_running on d.id = t_running.id and d.dates = t_running.dates
left join (
  select d.id, sum(d.sales) total_sales
  from dat d
  group by d.id    
) t_total on t_total.id = d.id

demo

请您提供一个示例,其中可以摆脱SELECT子查询?请非常友好,并添加一个工作示例链接(例如dbfiddlesqlfiddle),以便更容易理解,谢谢!

1 个答案:

答案 0 :(得分:0)

如果问题是针对多项选择测试(或类似的测试):),则不可能摆脱EXISTS子句的子查询。

IN (subquery)的另一个相似答案是不同聚合级别,以避免笛卡尔积。

(顺便说一句:相关子查询并非每次都被视为一种坏习惯,它取决于优化,结构等。

WITH是一种使用相关子查询的方法,它对复杂的查询非常实用。 )