Sql 如何在没有联合的情况下按日期范围分组
我有一个T-SQL查询(SQL2012),Sql 如何在没有联合的情况下按日期范围分组,sql,sql-server,tsql,range,union,Sql,Sql Server,Tsql,Range,Union,我有一个T-SQL查询(SQL2012),@START和@END是以前定义的 DECLARE @WEEK SMALLINT SET @WEEK = 7 WHILE @WEEK >= 0 BEGIN SELECT @START= (SELECT DATEADD( wk, -1, @START ) ) SELECT @END = (SELECT DATEADD( wk, -1, @END ) ) SELECT Visits.idPat
@START
和@END
是以前定义的
DECLARE @WEEK SMALLINT
SET @WEEK = 7
WHILE @WEEK >= 0
BEGIN
SELECT @START= (SELECT DATEADD( wk, -1, @START ) )
SELECT @END = (SELECT DATEADD( wk, -1, @END ) )
SELECT
Visits.idPatient,
Visits.VDay,
tblScheduledOrder.SDay
FROM
tblScheduledOrder
LEFT OUTER JOIN
(
SELECT
DATEPART( dw, VDate ) - 1 AS VDay,
idPatient
FROM
tblVisits
WHERE
( VDate >= @START ) AND
( VDate <= @END )
) AS Visits
ON tblScheduledOrder.idPatient = Visits.idPatient
SELECT @WEEK = @WEEK - 1
END
实际结果
--First resultset-----
|idPati SDay VDay |
|11 1 1 |
|12 2 2 |
|13 2 3 |
|14 3 3 |
|15 4 4 |
|16 4 5 |
--Second resulset-----
|11 1 1 |
|12 2 2 |
|13 2 3 |
|14 3 NULL |
|15 4 5 |
|16 4 5 |
----------------------
要求的结果
--Single resultset-----
|idPati SDay VDay |
|11 1 1 |
|12 2 2 |
|13 2 3 |
|14 3 3 |
|15 4 4 |
|16 4 5 |
|11 1 1 |
|12 2 2 |
|13 2 3 |
|14 3 NULL |
|15 4 5 |
|16 4 5 |
----------------------
我尝试了一个解决方案,但无法使我的结果与问题相一致,于是停止了。也许其他人可以更进一步。看到这个了吗 查询1:
declare @end as date
-- calculate "next" Monday
set @end = dateadd(d,-(datediff(d,0,getdate()) % 7)+7 ,cast(getdate() as date))
declare @start as date
set @start = dateadd(wk,-8,@end)
;with drange as (
select @start as dt, datepart(dw,@start) dw
union all
select dateadd(d,1,dt) , datepart(dw,dateadd(d,1,dt))
from drange
where dateadd(d,1,dt) <= @end
)
, p as (
select
SDay
, idPatient
, dateadd(d,SDay-1,dateadd(d,-datediff(d,0,getdate()) % 7,cast(getdate() as date))) Ndate
from tblScheduledOrder
)
select
dt, dw, p.Sday, vdate, ndate, coalesce(v.idpatient,p.idPatient) idpatient
from drange
left join tblVisits v on drange.dt = v.Vdate
left join p on drange.dt = p.Ndate
where drange.dw between 1 and 5
order by dt DESC, coalesce(v.idpatient,p.idPatient)
| dt | dw | Sday | vdate | ndate | idpatient |
|------------|----|--------|------------|------------|-----------|
| 2018-04-02 | 2 | (null) | (null) | (null) | (null) |
| 2018-04-01 | 1 | (null) | (null) | (null) | (null) |
| 2018-03-29 | 5 | 4 | 2018-03-29 | 2018-03-29 | 15 |
| 2018-03-29 | 5 | 4 | 2018-03-29 | 2018-03-29 | 15 |
| 2018-03-29 | 5 | 4 | 2018-03-29 | 2018-03-29 | 16 |
| 2018-03-29 | 5 | 4 | 2018-03-29 | 2018-03-29 | 16 |
| 2018-03-28 | 4 | 3 | (null) | 2018-03-28 | 14 |
| 2018-03-27 | 3 | 2 | 2018-03-27 | 2018-03-27 | 13 |
| 2018-03-27 | 3 | 2 | 2018-03-27 | 2018-03-27 | 13 |
| 2018-03-26 | 2 | 1 | 2018-03-26 | 2018-03-26 | 12 |
| 2018-03-25 | 1 | (null) | 2018-03-25 | (null) | 11 |
| 2018-03-22 | 5 | (null) | 2018-03-22 | (null) | 16 |
| 2018-03-21 | 4 | (null) | 2018-03-21 | (null) | 15 |
| 2018-03-20 | 3 | (null) | 2018-03-20 | (null) | 13 |
| 2018-03-20 | 3 | (null) | 2018-03-20 | (null) | 14 |
| 2018-03-19 | 2 | (null) | 2018-03-19 | (null) | 12 |
| 2018-03-18 | 1 | (null) | 2018-03-18 | (null) | 11 |
| 2018-03-15 | 5 | (null) | (null) | (null) | (null) |
| 2018-03-14 | 4 | (null) | (null) | (null) | (null) |
| 2018-03-13 | 3 | (null) | (null) | (null) | (null) |
| 2018-03-12 | 2 | (null) | (null) | (null) | (null) |
| 2018-03-11 | 1 | (null) | (null) | (null) | (null) |
| 2018-03-08 | 5 | (null) | (null) | (null) | (null) |
| 2018-03-07 | 4 | (null) | (null) | (null) | (null) |
| 2018-03-06 | 3 | (null) | (null) | (null) | (null) |
| 2018-03-05 | 2 | (null) | (null) | (null) | (null) |
| 2018-03-04 | 1 | (null) | (null) | (null) | (null) |
| 2018-03-01 | 5 | (null) | (null) | (null) | (null) |
| 2018-02-28 | 4 | (null) | (null) | (null) | (null) |
| 2018-02-27 | 3 | (null) | (null) | (null) | (null) |
| 2018-02-26 | 2 | (null) | (null) | (null) | (null) |
| 2018-02-25 | 1 | (null) | (null) | (null) | (null) |
| 2018-02-22 | 5 | (null) | (null) | (null) | (null) |
| 2018-02-21 | 4 | (null) | (null) | (null) | (null) |
| 2018-02-20 | 3 | (null) | (null) | (null) | (null) |
| 2018-02-19 | 2 | (null) | (null) | (null) | (null) |
| 2018-02-18 | 1 | (null) | (null) | (null) | (null) |
| 2018-02-15 | 5 | (null) | (null) | (null) | (null) |
| 2018-02-14 | 4 | (null) | (null) | (null) | (null) |
| 2018-02-13 | 3 | (null) | (null) | (null) | (null) |
| 2018-02-12 | 2 | (null) | (null) | (null) | (null) |
| 2018-02-11 | 1 | (null) | (null) | (null) | (null) |
| 2018-02-08 | 5 | (null) | (null) | (null) | (null) |
| 2018-02-07 | 4 | (null) | (null) | (null) | (null) |
| 2018-02-06 | 3 | (null) | (null) | (null) | (null) |
| 2018-02-05 | 2 | (null) | (null) | (null) | (null) |
问题是如何将所有这些都整合到一个结果集中,不是吗?使用临时表来存储循环结果,而不是使用应用程序。然后让应用程序从临时表中提取数据。(您可以使用常规表或#诱惑表。您只需要一个存放中间数据集的地方。)
DECLARE@tblPlaceHolder表(
Idpient BIGINT,
维迪·廷因特,
星期四,
第二周;
插入@tblPlaceHolder(
国内流离失所者,
星期五,
星期四,
(星期)
挑选
探视病人,
访问www.VDay,
tblScheduledOrder.SDay,
@每周-请提供样本数据和预期结果<代码>分组依据
以聚合值,但根据您的需求,您将显示所有访问以及实际访问date@maSTAShuFu是的,输出是计划的日期,在实际访问的同时,请访问sqlfiddle.com
或rextester.com
并弄脏您的数据。我认为,与其想出笨拙的方法来弯曲数据,不如以适合您使用的方式存储数据。当患者未在该周就诊时,开始在tblVisits中存储空条目,或者在tblScheduledOrder中存储每个患者每周的实际日期。如果存储了这些数据,您可以使用简单的JOIN@JackyCheng没错,但这需要一些应用程序每周在表上进行插入。有1.5万名患者,所以我猜这只是浪费了空间。。。也许我会重新考虑它的未来版本。现在,它需要以现在的方式解决。好主意,创建一个带有预期日期的动态tble,并将其与实际日期连接起来。我会把它标记为答案。几乎没有一种最好的方法可以做任何事情。但是,如果没有其他方法对你有效,而这是有效的,那么这可能是一个足够好的方法。
declare @end as date
-- calculate "next" Monday
set @end = dateadd(d,-(datediff(d,0,getdate()) % 7)+7 ,cast(getdate() as date))
declare @start as date
set @start = dateadd(wk,-8,@end)
;with drange as (
select @start as dt, datepart(dw,@start) dw
union all
select dateadd(d,1,dt) , datepart(dw,dateadd(d,1,dt))
from drange
where dateadd(d,1,dt) <= @end
)
, p as (
select
SDay
, idPatient
, dateadd(d,SDay-1,dateadd(d,-datediff(d,0,getdate()) % 7,cast(getdate() as date))) Ndate
from tblScheduledOrder
)
select
dt, dw, p.Sday, vdate, ndate, coalesce(v.idpatient,p.idPatient) idpatient
from drange
left join tblVisits v on drange.dt = v.Vdate
left join p on drange.dt = p.Ndate
where drange.dw between 1 and 5
order by dt DESC, coalesce(v.idpatient,p.idPatient)
| dt | dw | Sday | vdate | ndate | idpatient |
|------------|----|--------|------------|------------|-----------|
| 2018-04-02 | 2 | (null) | (null) | (null) | (null) |
| 2018-04-01 | 1 | (null) | (null) | (null) | (null) |
| 2018-03-29 | 5 | 4 | 2018-03-29 | 2018-03-29 | 15 |
| 2018-03-29 | 5 | 4 | 2018-03-29 | 2018-03-29 | 15 |
| 2018-03-29 | 5 | 4 | 2018-03-29 | 2018-03-29 | 16 |
| 2018-03-29 | 5 | 4 | 2018-03-29 | 2018-03-29 | 16 |
| 2018-03-28 | 4 | 3 | (null) | 2018-03-28 | 14 |
| 2018-03-27 | 3 | 2 | 2018-03-27 | 2018-03-27 | 13 |
| 2018-03-27 | 3 | 2 | 2018-03-27 | 2018-03-27 | 13 |
| 2018-03-26 | 2 | 1 | 2018-03-26 | 2018-03-26 | 12 |
| 2018-03-25 | 1 | (null) | 2018-03-25 | (null) | 11 |
| 2018-03-22 | 5 | (null) | 2018-03-22 | (null) | 16 |
| 2018-03-21 | 4 | (null) | 2018-03-21 | (null) | 15 |
| 2018-03-20 | 3 | (null) | 2018-03-20 | (null) | 13 |
| 2018-03-20 | 3 | (null) | 2018-03-20 | (null) | 14 |
| 2018-03-19 | 2 | (null) | 2018-03-19 | (null) | 12 |
| 2018-03-18 | 1 | (null) | 2018-03-18 | (null) | 11 |
| 2018-03-15 | 5 | (null) | (null) | (null) | (null) |
| 2018-03-14 | 4 | (null) | (null) | (null) | (null) |
| 2018-03-13 | 3 | (null) | (null) | (null) | (null) |
| 2018-03-12 | 2 | (null) | (null) | (null) | (null) |
| 2018-03-11 | 1 | (null) | (null) | (null) | (null) |
| 2018-03-08 | 5 | (null) | (null) | (null) | (null) |
| 2018-03-07 | 4 | (null) | (null) | (null) | (null) |
| 2018-03-06 | 3 | (null) | (null) | (null) | (null) |
| 2018-03-05 | 2 | (null) | (null) | (null) | (null) |
| 2018-03-04 | 1 | (null) | (null) | (null) | (null) |
| 2018-03-01 | 5 | (null) | (null) | (null) | (null) |
| 2018-02-28 | 4 | (null) | (null) | (null) | (null) |
| 2018-02-27 | 3 | (null) | (null) | (null) | (null) |
| 2018-02-26 | 2 | (null) | (null) | (null) | (null) |
| 2018-02-25 | 1 | (null) | (null) | (null) | (null) |
| 2018-02-22 | 5 | (null) | (null) | (null) | (null) |
| 2018-02-21 | 4 | (null) | (null) | (null) | (null) |
| 2018-02-20 | 3 | (null) | (null) | (null) | (null) |
| 2018-02-19 | 2 | (null) | (null) | (null) | (null) |
| 2018-02-18 | 1 | (null) | (null) | (null) | (null) |
| 2018-02-15 | 5 | (null) | (null) | (null) | (null) |
| 2018-02-14 | 4 | (null) | (null) | (null) | (null) |
| 2018-02-13 | 3 | (null) | (null) | (null) | (null) |
| 2018-02-12 | 2 | (null) | (null) | (null) | (null) |
| 2018-02-11 | 1 | (null) | (null) | (null) | (null) |
| 2018-02-08 | 5 | (null) | (null) | (null) | (null) |
| 2018-02-07 | 4 | (null) | (null) | (null) | (null) |
| 2018-02-06 | 3 | (null) | (null) | (null) | (null) |
| 2018-02-05 | 2 | (null) | (null) | (null) | (null) |
Declare @StartDate DateTime ='20180301'
Declare @EndDate DateTime ='20180330'
DECLARE @NotVisitedPatients table ( idPatient Int ,Sday INT , Vdate Date,Vday int ,WeekNumber INT )
DECLARE @WeekNumber table ( Id Int identity (1,1) ,WeekNumber INT )
INSERT INTO @WeekNumber
SELECT distinct
DATEPART(Week ,V.[VDate])
FROM [dbo].[tblVisits] V
inner join [dbo].[tblScheduledOrder] S on V.idPatient = S.idPatient
where V.[VDate] between @StartDate and @EndDate
declare @Total int = (select Max(Id) from @WeekNumber)
declare @count int =1
declare @week int = 0
WHILE (@Total >= @count)
BEGIN
set @week =(select WeekNumber from @WeekNumber where id =@count)
print @week
INSERT INTO @NotVisitedPatients
(idPatient
,Sday
,Vdate
,Vday
,WeekNumber)
select distinct S.idPatient ,S.Sday ,null,null, @week from tblScheduledOrder S
where S.idPatient not in (select V.idPatient from tblVisits V
where DATEPART(Week ,V.[VDate]) = @week)
set @count =@count +1
END
select idPatient ,Sday , Vdate,Vday ,WeekNumber from @NotVisitedPatients
Union
SELECT distinct S.idPatient
,S.Sday
,V.[VDate]
, DATEPART(DW ,V.[VDate]) As VDay
, DATEPART(Week ,V.[VDate]) As WeekNumber
FROM [dbo].[tblVisits] V
inner join [dbo].[tblScheduledOrder] S on V.idPatient = S.idPatient
where V.[VDate] between @StartDate and @EndDate
DECLARE @tblPlaceHolder TABLE (
idPatient BIGINT,
VDay TINYINT,
SDay TINYINT,
Week SMALLINT);
<Your existing loop code except add this: >
INSERT INTO @tblPlaceHolder (
idPatient,
VDay,
SDay,
Week)
SELECT
Visits.idPatient,
Visits.VDay,
tblScheduledOrder.SDay,
@WEEK AS Week --<-------Addition to SELECT
FROM
tblScheduledOrder
LEFT OUTER JOIN....
<The rest of your loop code>
SELECT @WEEK = @WEEK - 1
END
SELECT
idPatient,
SDay,
VDay
FROM
@tblPlaceHolder
ORDER BY
Week DESC, --Not needed in the result set. Just to sort by.
SDay,
idPatient;