我有这个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.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
患者的“预定访问”有一个表格(患者时间表是每周一次,即访问应该在每个星期一进行)。 tblScheduledVisit
由2个字段(tblScheduledOrder.idPatient
和tblScheduledOrder.SDay
)组成。
实际访问次数存储在tblVisits
,其中包含(tblVisits.VDate
,tblVisits.idPatient
)
我需要提供患者过去8周的清单,以及他们预定日期和实际日期之间的关系。
正如你所看到的,我做了几个选择然后我在应用程序中建立一个联合,这不是正确的方法,对吗?
--tblScheduledOrder-- ----tblVisits--------
|SDay idPatient | |idPatient VDate | DATEPART(dw)
| 1 11 | |11 #2018-3-18# | 1
| 2 12 | |12 #2018-3-19# | 2
| 2 13 | |13 #2018-3-20# | 3
| 3 14 | |14 #2018-3-20# | 3
| 4 15 | |15 #2018-3-21# | 4
| 4 16 | |16 #2018-3-22# | 5
--------------------- |11 #2018-3-25# | 1
|12 #2018-3-26# | 2
|13 #2018-3-27# | 3
|15 #2018-3-29# | 5
|16 #2018-3-29# | 5
---------------------
实际结果
--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 |
----------------------
答案 0 :(得分:0)
我尝试了一个解决方案,但无法将我的结果与问题进行协调并停止。也许其他人可以更进一步。请参阅此SQL Fiddle
CREATE TABLE tblScheduledOrder
(SDay int, idPatient int)
;
INSERT INTO tblScheduledOrder
(SDay, idPatient)
VALUES
(1, 11),
(2, 12),
(2, 13),
(3, 14),
(4, 15),
(4, 16)
;
CREATE TABLE tblVisits
(idPatient int, VDate date)
;
INSERT INTO tblVisits
(idPatient, VDate)
VALUES
(11, '2018-03-18'),
(12, '2018-03-19'),
(13, '2018-03-20'),
(14, '2018-03-20'),
(15, '2018-03-21'),
(16, '2018-03-22'),
(11, '2018-03-25'),
(12, '2018-03-26'),
(13, '2018-03-27'),
(15, '2018-03-29'),
(16, '2018-03-29')
;
查询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)
<强> Results 强>:
| 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) |
答案 1 :(得分:0)
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
答案 2 :(得分:0)
问题是如何将这一切都集成到一个结果集中,不是吗?而不是使用应用程序,使用临时表来存储循环结果。然后让应用程序从临时表中获取它的数据。 (您可以使用常规表或#TempTable。您只需要一个位置来停放中间数据集。)
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;