匿名用户SQL 数据库 with tablename as 跟临时表有什么区别?
1、with tempTableName as
with temptable as 其实并没有建立临时表,只是子查询部分(subquery factoring),定义一个SQL片断,该SQL片断会被整个SQL语句所用到。它的好处是增加了代码的可读性和进行维护。
有的时候,是为了让SQL语句的可读性更高些,也有可能是在UNION ALL的不同部分,作为提供数据的部分。特别对于UNION ALL比较有用。因为UNION ALL的每个部分可能相同,但是如果每个部分都去执行一遍的话,则成本太高,所以可以使用WITH AS短语,则只要执行一遍即可。
--设计累计发生
with ljfssj as (
select b.ProjGUID,
COUNT(*) Ljfscs, --累计发生次数
SUM(ISNULL(a.ApproveAmount_Bz,0)) ljfsAmount --累计发生金额
from cb_DesignAlterToContract a
left join cb_DesignAlter b on a.DesignAlterGuid = b.DesignAlterGUID
where b.ApproveStatusEnum = 3 and b.x_IsManagement <> 1 and b.ReportDate <= @jzdate group by b.ProjGUID
),
--设计本期发生
bqfssj as (
select b.ProjGUID,
COUNT(*) bqfscs, --本次发生次数
SUM(ISNULL(a.ApproveAmount_Bz,0)) bqfsAmount --本次发生金额
from cb_DesignAlterToContract a
left join cb_DesignAlter b on a.DesignAlterGuid = b.DesignAlterGUID
where b.ApproveStatusEnum = 3 and b.x_IsManagement <> 1 and b.ReportDate between @ksdate and @jzdate group by b.ProjGUID
),
--设计累计确认
ljqrsj as (
select b.ProjGUID,
COUNT(*) ljqrcs, --累计确认次数
SUM(ISNULL(c.ValidationAmount_Bz,0)) ljqrAmount --累计确认金额
from cb_DesignAlterToContract a
inner join cb_DesignAlter b on a.DesignAlterGuid = b.DesignAlterGUID
left join cb_DesignAlterZJSP c on a.DesignAlterGuid = c.DesignAlterGUID and a.ContractGUID = c.ContractGUID
where b.ApproveStatusEnum = 3 and b.x_IsManagement <> 1 and b.ReportDate <= @jzdate group by b.ProjGUID
)
2、临时表
临时表的数据是需要插入到数据库的,所以一般用于做报表的话,在插入数据之后需要删除临时表。
临时表与永久表相似,只是它的创建是在Tempdb中,它只有在一个数据库连接结束后或者由SQL命令DROP掉,才会消失,否则就会一直存在(临时表一般被创建后,如果在执行的时候,没有通过DROP Table的操作,第二次就不能再被创建)。临时表在创建的时候都会产生SQL Server的系统日志,虽它们在Tempdb中体现,是分配在内存中的,它们也支持物理的磁盘,但用户在指定的磁盘里看不到文件。
临时表分为本地和全局两种,本地临时表的名称都是以“#”为前缀,只有在本地当前的用户连接中才是可见的,当用户从实例断开连接时被删除。全局临时表的名称都是以“##”为前缀,创建后对任何用户都是可见的,当所有引用该表的用户断开连接时被删除。
if OBJECT_ID('tempdb..#f1') is not null
drop table #f1
SELECT
Getin.ProjGUID,
Getin.BldGUID,
Getin.TopProductTypeGUID,
SUM(ISNULL(CurrGetin.CurrHjAmount, 0)) AS F1
into #f1 FROM data_wide_s_Getin Getin WITH(NOLOCK)
LEFT JOIN ( SELECT GetinGUID,
SUM(CASE WHEN ItemType='非贷款类房款'
AND IsFk = 1
OR ItemNameGUID = '9165FAED-227A-465D-AA5D-D24BED655677' /*银行按揭*/
OR ItemNameGUID = 'C3190DC3-C295-4A98-B7AC-9DFF7D7A0091' /*公积金*/ THEN ISNULL(RmbAmount, 0)ELSE 0 END) AS CurrHjAmount
FROM data_wide_s_Getin WITH(NOLOCK)
WHERE
--ProjGUID IN (@ProjGuids)
-- AND
VouchStatus <> '作废'
AND CONVERT(VARCHAR(100), SkDate, 23) >= CONVERT(VARCHAR(100), @BeginDate, 23)
AND CONVERT(VARCHAR(100), SkDate, 23) <= CONVERT(VARCHAR(100), @EndDate, 23)
GROUP BY GetinGUID ) AS CurrGetin
ON Getin.GetinGUID = CurrGetin.GetinGUID
GROUP BY Getin.ProjGUID,Getin.BldGUID,Getin.TopProductTypeGUID
3.运行效率
用with tempTableName as ,其实跟直接用子查询效率上没有什么区别;而用临时表与永久表相似,数据是真是跑入到数据库里面去的,相当于第二次直接关联的是一个小表,查询效率大大提高。
4.应用场景
临时表适用于:有很多复杂的关联子表查询。
with tempTableName as 适用于:为了增加代码可读性,且没有很多复杂的关联子查询。
参考:https://www.cnblogs.com/zhaowei303/articles/4204805.html
https://blog.csdn.net/weixin_42039637/article/details/108754400
评论
有用 0
墨值悬赏

