我有下面的SQL查询,我想重构它。我对SQL非常陌生,但我已经学到了一些不该在查询中重复执行的内容。
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 *,所以我用以下方式替换了每个事件:
SELECT COUNT(randomID)这给了我同样的结果。不过,我仍然认为可以将重复的元素组合成一个更简洁的查询,但是我的SQL级别还不够好。
有什么方法可以重构这段代码以避免重复类似的查询呢?
发布于 2018-09-15 02:14:01
一种简单的方法使用apply
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()。
select t3.id, t1.col1_cnt, t2.col2_cnt,
t2.col2_cnt * 100.0 / nullif(t1.col1_cnt, 0) as col3_percentage发布于 2018-09-14 23:37:10
对于计数,您可以将这些表合并在一起;如下所示:
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)就足够聪明,不会实际选择任何列。因此,假设您只想计算每一行(甚至是空行),所有这些都是等效的。
select
count(1),
count(*),
count(primarykeycolumn) -- guaranteed not to be null
from myTable发布于 2018-09-15 07:08:05
我的主张:
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.randomIDhttps://stackoverflow.com/questions/52340290
复制相似问题