首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >重构SQL查询

重构SQL查询
EN

Stack Overflow用户
提问于 2018-09-14 23:23:05
回答 3查看 1.1K关注 0票数 0

我有下面的SQL查询,我想重构它。我对SQL非常陌生,但我已经学到了一些不该在查询中重复执行的内容。

代码语言:javascript
复制
SELECT id,
(​SELECT​ ​COUNT​(*)​ ​FROM​ Table_1 ​
WHERE​ T3.​Id ​=​ randomID)​ ​AS​ ​'Column One Count'​,

(​SELECT​ ​COUNT​(*)​ ​FROM​ Table_2 ​
WHERE​ T3.​Id ​=​ randomID)​ ​AS​ ​'Column Two Count'​,

((​SELECT​ ​COUNT​(*)​ ​FROM​ Table_2 
​WHERE​ T3.​Id ​=​ randomID)​ ​/​

(​SELECT COUNT​(*)​ ​FROM​ Table_1 ​
WHERE​ T3.​Id ​=​ randomID))​ ​*​ 100 ​AS​ 'Column Three Percentage' 
FROM Table_3 T3

我被告知不要经常使用SELECT *,所以我用以下方式替换了每个事件:

代码语言:javascript
复制
SELECT COUNT(randomID)

这给了我同样的结果。不过,我仍然认为可以将重复的元素组合成一个更简洁的查询,但是我的SQL级别还不够好。

有什么方法可以重构这段代码以避免重复类似的查询呢?

EN

回答 3

Stack Overflow用户

发布于 2018-09-15 02:14:01

一种简单的方法使用apply

代码语言:javascript
复制
select t3.id, t1.col1_cnt, t2.col2_cnt,
       t2.col2_cnt * 100.0 / t1.col1_cnt as col3_percentage
from Table_3 t3 outer apply
     (select count(*) as col1_cnt
      from table_1 t1
      where t3.id = t1.randomid
     ) t1 outer apply
     (select count(*) as col2_cnt
      from table_2 t2
      where t3.id = t2.randomid
     ) t2;

apply本质上允许将相关子查询移动到from子句。一旦它们在那里,您就可以引用它们生成的列多次。

编辑:

如果您关心的是除以零,那么使用nullif()

代码语言:javascript
复制
select t3.id, t1.col1_cnt, t2.col2_cnt,
       t2.col2_cnt * 100.0 / nullif(t1.col1_cnt, 0) as col3_percentage
票数 2
EN

Stack Overflow用户

发布于 2018-09-14 23:37:10

对于计数,您可以将这些表合并在一起;如下所示:

代码语言:javascript
复制
select Ct = count(1)
from table_1
where Id = @RandomId
union 
select count(1)
from table_2
where Id = @RandomId'

我还没有充实所有的专栏,但希望总的想法是有意义的。

通常,就select *的内容而言,出于许多原因(包括可能需要的数据比您可能需要的更多,容易受到模式更改的影响,以及在膝盖上大量生成非聚集索引),您是正确的。在较早版本的SQL中,扩展到类似于count(*)的内容。但是,只要您使用的是SQL 2008+,count() (以及其他几个子句,如EXISTS)就足够聪明,不会实际选择任何列。因此,假设您只想计算每一行(甚至是空行),所有这些都是等效的。

代码语言:javascript
复制
select 
    count(1),
    count(*),  
    count(primarykeycolumn) -- guaranteed not to be null
from myTable
票数 1
EN

Stack Overflow用户

发布于 2018-09-15 07:08:05

我的主张:

代码语言:javascript
复制
With CountT1 as (
select f1.randomID, count(*) NbT1
from Table_1 f1 inner join Table_3 f3 on f3.Id=f1.randomID
group by f1.randomID
),
CountT2 as (
select f1.randomID, count(*) NbT2
from Table_2 f1 inner join Table_3 f3 on f3.Id=f1.randomID
group by f1.randomID
)
select T3.Id, 
isnull(T1.NbT1, 0) as ​'Column One Count', 
isnull(T2.NbT2, 0) as ​'Column Two Count', 
case when T1.NbT1=0 then null else (T2.NbT2 /  T1.NbT1) * 100.0 end  as 'Column Three Percentage'
from Table_3 T3
left outer join CountT1 T1 on T3.Id=T1.randomID
left outer join CountT2 T2 on T3.Id=T2.randomID
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52340290

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档