Sql 如何最小化子查询的使用

Sql 如何最小化子查询的使用,sql,tsql,Sql,Tsql,我有下面的表格,我想计算销售数字。我使用了一些子查询。我可以不使用子查询而不使用表变量来完成吗 TableA, 4 columns - popuplation pkeyP | population | city | country some data 100, 1234, london, UK 101, 2345, oxford, UK 102, 3345, bristol, UK 103, 1256, new york, USA 104, 5424, LA, USA 105, 100, be

我有下面的表格,我想计算销售数字。我使用了一些子查询。我可以不使用子查询而不使用表变量来完成吗

TableA, 4 columns - popuplation pkeyP | population | city | country some data 100, 1234, london, UK 101, 2345, oxford, UK 102, 3345, bristol, UK 103, 1256, new york, USA 104, 5424, LA, USA 105, 100, beijing, China Table B, 4 columns - sales_amount pkeyA | amount | city | country some data 200, 105, london, UK 201, 210, oxford, UK 203, 23, new york, USA 204, 54, LA, USA the city in first table may not exist in second table 子查询1将返回 英国,6924 美国,6680 中国,100 子查询2将返回 英国,315 美国,77 最终结果 英国,6924315 美国,6680,77, 中国,100,零 这就是一个例子。我的实际查询有许多这样的小表,我需要先进行分组,然后进行连接以进行最终计算


我不想使用子查询,因为我的实表有很多列,而实查询非常长。它非常不可读,很难维护。

您可以执行以下操作,将单个查询结果合并为一个查询结果,如下所示

select aa.country, aa.popu, bb.amou,cc.smou from 
    (select sum(population) as popu, country from population group by country) aa
inner join 
    (select sum(amount) as amou, country from sales_amount group by countr) bb
on aa.country = bb.country inner join
    (select sum(sales) as smou, country from sales_amount group by countr) cc
on bb.country = cc.country
-- inner join ..  so on as you wrote....

编辑,好的,那么为什么不在已经完成聚合的地方创建视图呢,特别是如果这是您经常使用的信息的话。如果可读性是您主要关心的问题,那么这应该会有所帮助。例如:

CREATE VIEW vw_aggregated_population AS
SELECT sum(population) AS popu, country 
FROM population GROUP BY country

CREATE VIEW vw_aggregated_sales_amount AS
SELECT sum(amount) AS amou, country 
FROM sales_amount GROUP BY country

SELECT
vw_aggregated_population.country,
popu, 
amou,
FROM vw_aggregated_population
LEFT JOIN vw_aggregated_sales_amount
ON vw_aggregated_population.country=vw_aggregated_sales_amount.country
GROUP BY vw_aggregated_population.country

您可以使用
full join
groupby
union all
来获取所有表中的所有行。下面是使用第二种方法的示例:

with p as (
      select sum(population) as population, country
      from population
      group by country
     ),
     sa as (
      select sum(amount) as amount, country
      from sales_amount
      group by country
     ) 
select country, max(population), max(amount)
from ((select country, population, null as amount
       from p
      ) union all
      (select country, null, amount
       from sa
      )
     ) ps
group by country;

应该清楚如何扩展更多表。

示例数据和预期结果将帮助我们帮助您。这似乎是一种合理的方法。为什么要更改它?但是,很可能至少需要一个子查询。为什么不将所有表合并并在末尾调用一个groupby,而总是在子查询中执行groupby?查询优化器应该足够聪明,能够弄清楚如何做到这一点efficiently@Karl:因为这些连接是多对多的,求和是完全错误的这与原始查询相同,只是连接的另一种顺序,没有人会使用:-)好的,当一个人想要将来自不同表的结果合并到一个查询结果中时,我看不到任何其他读取结果的选项!除了写一个CTE或者创建一个视图或者类似的东西,因为这些连接是多对多的,并且总和是完全错误的。由于行数爆炸式增长,额外的性能将非常糟糕。好的,您应该在问题中说明这一点。请参阅更新的答案这很明显,为什么要按一个已经唯一的列进行分组?我在这么多问题中看到了这么多这样的事情,你会感到惊讶……因为涉及到许多表,而我们不知道数据大小。那么,从性能角度来看,您更喜欢哪一种?全部与group by完全联接或联合。@AnkitBajpai。我使用了
union-all
方法,因为它更容易泛化。实际上,我不确定哪一个在SQLServer中工作得更好。如果您有大量数据,那么比较性能是值得的<与其他
JOIN
相比,code>FULL JOIN有一些额外的开销<代码>分组依据也有开销。但是,如果在每个子表中都有关于
国家
的索引,那么
分组依据
应该是非常合理的。
SELECT
vw_aggregated_population.country,
popu, 
amou,
FROM vw_aggregated_population
LEFT JOIN vw_aggregated_sales_amount
ON vw_aggregated_population.country=vw_aggregated_sales_amount.country
GROUP BY vw_aggregated_population.country
with p as (
      select sum(population) as population, country
      from population
      group by country
     ),
     sa as (
      select sum(amount) as amount, country
      from sales_amount
      group by country
     ) 
select country, max(population), max(amount)
from ((select country, population, null as amount
       from p
      ) union all
      (select country, null, amount
       from sa
      )
     ) ps
group by country;