SQL Server错误由于多个联接而简化代码

SQL Server错误由于多个联接而简化代码,sql,sql-server-2008,tsql,sql-server-2005,Sql,Sql Server 2008,Tsql,Sql Server 2005,我需要另一种方法来简化这段代码 此代码根据贷款还款计划计算客户余额的账龄。过滤时间为1-7天、8-30天、31-60天。。。。以此类推,直到达到181及以上 with membersWithLoans as -- gets members with loan ( select a.memberid, a.loanid, a.loanamt, a.intamt from loanmst a where loandt &l

我需要另一种方法来简化这段代码

此代码根据贷款还款计划计算客户余额的账龄。过滤时间为1-7天、8-30天、31-60天。。。。以此类推,直到达到181及以上

with membersWithLoans as -- gets members with loan
(
    select 
        a.memberid, a.loanid, a.loanamt, a.intamt
    from 
        loanmst a
    where 
        loandt <= '12/19/2016'
        and status = 'O'
)
,selectPaymentToDate as -- gets payments of the members to date
(
    select 
        b.loanid, sum(a.princollamt) as princollamt1, 
        sum(a.intcollamt) as intcollamt1
    from 
        collectiondtl a
    inner join 
        membersWithLoans b on a.loanid = b.loanid
    where 
        a.accdate <= '12/19/2016'
    group by 
        b.loanid)
,selectBalanceToDate as -- gets the balance of member to date
(
    select 
        b.loanid, 
        sum(a.princeamt) as prinBalanceToDate, 
        sum(a.instamt) as intBalanceToDate,
        sum(a.insamt) as insuBalanceToDate
    from 
        loandtl a
    inner join 
        membersWithLoans b on a.loanid = b.loanid
    where 
        a.duedt <= '12/19/2016'
    group by 
        b.loanid)
, combineBalanceWithpayment as -- combine payment and balance
(
    select a.loanid,a.loanamt, a.intamt, 
(case
when b.prinBalanceToDate is null then 0
else b.prinBalanceToDate end) as prinBalanceToDate2,
(case
when b.intBalanceToDate is null then 0
else b.intBalanceToDate end) as intBalanceToDate2,
(case
when b.insuBalanceToDate is null then 0
else b.insuBalanceToDate end) as insuBalanceToDate2,
(case
when c.princollamt1 is null then 0
else c.princollamt1 end) as PrincipalCollectiontoDate,
(case
when c.intcollamt1 is null then 0
else c.intcollamt1 end) as IntCollectiontoDate,

cast(((case
when b.prinBalanceToDate is null then 0
else b.prinBalanceToDate 
end)
-
(case
when c.princollamt1 is null then 0
else c.princollamt1 end))as decimal(10,2)) as Arrears
from
membersWithLoans a
left join selectBalanceToDate b
on a.loanid=b.loanid
left join selectPaymentToDate c
on a.loanid=c.loanid
)

,filterNegativeArrears as
(
select * 
from
combineBalanceWithpayment
where Arrears > 0
)
select a.*,
b.Par1To7days,
c.Par8To30days,
d.Par31To60days,
e.Par61To90days,
f.Par91To120days,
g.Par121To180days --,
--h.Par181AndAbovedays
from

filterNegativeArrears a
left join computePar1To7days b
on a.loanid=b.loanid
left join computePar8To30days c
on a.loanid=c.loanid
left join computePar31To60days d
on a.loanid=d.loanid
left join computePar61To90days e
on a.loanid=e.loanid
left join computePar91To120days f
on a.loanid=f.loanid
left join computePar121To180days g
on a.loanid=g.loanid
--left join computePar181AndAbovedays h
--  on a.loanid=h.loanid
上面的代码加入了计算年龄

代码运行良好,计算良好

但是当我在选择中添加更多的连接时,我会得到一个错误

left join computePar181AndAbovedays h
on a.loanid=h.loanid
问题是我开始遇到错误:

已达到expression services限制。请找 查询中可能存在复杂的表达式,请尝试简化 他们

我仍然需要更多的表来加入我的查询


您能提出简化此查询的方法吗?我们非常感谢您

您显然遇到了一个限制,您的查询不可能达到这个限制。遵循错误消息中给出的建议:简化

怎么做?好吧,你有很多CTE的定义。编写查询的另一种方法是在实际查询之前在临时表中具体化CTE,然后使用临时表


例如,本CTE:

membersWithLoans as -- gets members with loan
(
select a.memberid, a.loanid,a.loanamt,a.intamt
from loanmst a
where loandt<='12/19/2016'
and status = 'O'
)

旁注:您应该绝对避免在任何查询中使用特定于语言环境的日期格式。例如
DATEADD(日期-7,'12/19/2016')
在您的查询中。始终使用ISO格式,如中所示。格式:
YYYY-MM-DD
yyyyymmdd
@Mandz-Hi-Mandz。不,您在
WITH
子句中定义的是CTE的aka公共表表达式。将它们与您临时定义用于一个查询的视图进行比较。CTE没有实现;当您的查询运行时,CTE在您的查询中被展开,类似于使用派生表编写查询的方式。这对我来说是一个新代码。我会试着在临时桌子上看书。我认为sql“with子句”是临时表。我想问一个问题,我可以用新的临时表连接当前的子查询吗?示例我将把我的输出放在一个temp1中,然后我将把temp1连接到前面的子查询?@Mandz是的,您可以。我将快速更新我的答案以进行说明。此查询正在从我的程序馈送到数据库。我的问题是,在从联接表中得到最终结果之后,是否需要一些代码来处理临时表?我调用了代码dbsqlConnect.Close();。这张临时桌子会留下来还是会被擦去?坦率地说,我使用这个查询生成计算报告。这样我就知道如何适应我的计划。泰铢time@Mandz如果您有来自JBoss应用程序服务器的连接池,那么肯定必须在
SELECT
语句之后立即删除临时表。因此,您的查询将是完整的:(1)创建临时表,(2)引用临时表的select语句,最后(3)删除在步骤1中创建的所有临时表(例如
drop TABLE#filternegative欠款;drop TABLE…
)。这是一个集所有功能于一体的SQL脚本。
membersWithLoans as -- gets members with loan
(
select a.memberid, a.loanid,a.loanamt,a.intamt
from loanmst a
where loandt<='12/19/2016'
and status = 'O'
)
select a.memberid, a.loanid,a.loanamt,a.intamt
into #membersWithLoans
from loanmst a
where loandt<='12/19/2016'
and status = 'O'
-- create all temporary tables (one of them being #filterNegativeArrears)

select 
    a.*,
    -- the rest of your selections
from
    #filterNegativeArrears a
    -- the rest of the joined temporary tables
-- the rest of your query (WHERE, ORDER BY etc)