我如何实现以下内容:
declare @myInt int
set @myInt=(select count(*) from x)
;with x as
(
select row_number() over(partition by c.patientid order by c.admissiondate) as rn
,c.patientid,c.admissiondate
,max(c.claimsfromdate) as maxHemiDate
,min(c.claimsfromdate) minHemiDate
,(
select max(c2.claimsfromdate)
from claims as c2
where c2.patientid=c.patientid
group by c2.patientid
) as maxClaimsDate
,p.drgCode
,datediff(dd,min(c.claimsfromdate),max(c.claimsfromdate)) /7 as weeksWithHemi
from claims as c inner join icdclaims as ci on ci.id=c.id
inner join tblicd as t on t.icd_id=ci.icd_id
inner join patient as p on p.patientid=c.patientid
and p.admissiondate = c.admissiondate
and p.dischargedate = c.dischargedate
where t.icdText like '%X%' and p.statecode='21'
group by c.patientid, c.admissiondate, p.drgCode
)
select p.patientid, count(*)
from patient as p
left join x on x.patientid=p.patientid
where x.patientid is null
group by p.patientid
执行此操作时抛出的错误是
无效的对象名称x
我有点认为,由于变量声明在CTE之外,所以会发生这种情况。如果我在WITH
的括号内移动声明,我会收到另一个错误。
如何在CTE中分配这样的变量?或者你可以不使用从CTE中提取数据的变量吗?
答案 0 :(得分:3)
要获取@myInt行数,您可以执行以下操作:
declare @myInt int
;with x as
(
__your query__
)
select p.patientid, count(*)
from patient as p
left join x on x.patientid=p.patientid
where x.patientid is null
group by p.patientid
set @myInt=@@ROWCOUNT
已编辑 (由于Jon Egerton评论)如果您需要计算x行,那么临时表就是这样:
declare @myInt int
;with x as
(
__your query__
)
select *
into #tmp_x
from x;
set @myInt=(select count(*) from #tmp_x)
select p.patientid, count(*)
from patient as p
left join #tmp_x x on x.patientid=p.patientid
where x.patientid is null
group by p.patientid
感谢Jon Egerton
答案 1 :(得分:3)
如果您使用的是SQL Server 2005或更高版本,则可以在每行上添加总计:
select t.*, cnt, count(*) over () as NumRows
from (select p.patientid, count(*) as cnt
from patient as p left join
x
on x.patientid=p.patientid
where x.patientid is null
group by p.patientid
) t
如果您使用总计来计算百分比或类似的东西,那么在每一行上获得值可能会很方便。
答案 2 :(得分:2)
问题在于这一行:
set @myInt=(select count(*) from x)
您正在尝试在声明之前对x
进行选择!
<强>更新强>
在这种情况下,最好使用临时表或表变量而不是CTE。例如:
declare @myInt int
select row_number() over(partition by c.patientid order by c.admissiondate) as rn
,c.patientid,c.admissiondate
,max(c.claimsfromdate) as maxHemiDate
,min(c.claimsfromdate) minHemiDate
,(
select max(c2.claimsfromdate)
from claims as c2
where c2.patientid=c.patientid
group by c2.patientid
) as maxClaimsDate
,p.drgCode
,datediff(dd,min(c.claimsfromdate),max(c.claimsfromdate)) /7 as weeksWithHemi
INTO #XTable
from claims as c inner join icdclaims as ci on ci.id=c.id
inner join tblicd as t on t.icd_id=ci.icd_id
inner join patient as p on p.patientid=c.patientid
and p.admissiondate = c.admissiondate
and p.dischargedate = c.dischargedate
where t.icdText like '%X%' and p.statecode='21'
group by c.patientid, c.admissiondate, p.drgCode
set @myInt=(select count(*) from #XTable)
select p.patientid, count(*)
from patient as p
left join #XTable x on x.patientid=p.patientid
where x.patientid is null
group by p.patientid
这是一种快速而肮脏的方法,但您可以在脚本中更早地声明您的表。
答案 3 :(得分:2)
您不能将单个CTE
用于两个不同的语句 - 它们超出范围。
因此,您需要删除对变量的需求,或者您只需声明一个表变量,然后根据需要继续选择该变量。
您可以按如下方式声明表格变换:
declare @x table (rowno int, patientid varchar...
然后,您可以使用您目前在CTE中获得的选择来填写该内容。
答案 4 :(得分:0)
CTE可以是复数。它并没有解决你所陈述的问题,但将复杂的CTE分解为几个步骤往往更加清晰,每个步骤都建立在先前的定义之上。在这个例子中,有一个递归CTE和第二个CTE,它根据第一个计算统计数据。最终SELECT
结合了结果:
with CTE
as (
select 1 as Number
union all
select Number + 1
from CTE
where Number < 10
),
Summary
as (
select Count( 42 ) as HowMany, Min( Number ) as Least, Max( Number ) as Most
from CTE
)
select *
from CTE cross join
Summary