求1关于时间分配的高效查询(sql2000)
求一关于时间分配的高效查询(sql2000)
--求一高效的查询(sql2000)
有两个表#a及#b
--#a有编码,开始时间,需要的分钟数,计划开始时间,计划结束时间
--#B有编码,开始时间,结止时间(#b数据量比较大)
要求计算出#a的计划开始时间,计划结止时间
按#a编码及开始时间在#b最可以最早的可以开始时间,
然后将#a给定的分钟数,在#b中顺次扣减,计算出#a的计划结束时间
并更新到#a的fbdt,fedt
可以理解为a表给出开始时间及需要的分钟数,
在b表实际每个编码可以使用的时间分配记录,
计算出a在B可以最早的开始及结束时间
create table #a(code char(10),bdt datetime,fz int ,fbdt datetime null,fedt datetime null
create table #b(code char(10),bdt datetime,edt datetime)
--示例数据
insert into #a(code,bdt,fz)
select 'a01','2014-09-02 08:00',200
union
select 'a01','2014-09-05 09:00',560
insert into #b(code,bdt,edt)
select 'a01','2014-09-02 05:00','2014-09-02 07:00'
union
select 'a01','2014-09-02 09:00','2014-09-02 12:00'
union
select 'a01','2014-09-02 13:00','2014-09-02 17:00'
union
select 'a01','2014-09-05 06:00','2014-09-05 08:30'
union
select 'a01','2014-09-05 09:00','2014-09-05 12:00'
union
select 'a01','2014-09-05 13:00','2014-09-05 18:00'
union
select 'a01','2014-09-06 08:00','2014-09-06 12:00'
结果如下,
select code,bdt,fz,fbdt,fedt
from #ta
/*
a01,2014-09-02 08:00,300,2014-09-02 09:00,2014-09-02 13:20
a01,2014-09-05 09:00,300,2014-09-05 09:00,2014-09-06 09:20
*/
计算过程:
第一行a01开始时间为2014-09-02 08:00,200分钟,在#b中找到最早在2014-09-02 08:00及以后的记录,为2014-09-02 09:00,
即以2014-09-02 09:00为计划开始时间,在b表中从2014-09-02 09:00开始使用200分钟,
b表2014-09-02 09:00-->2014-09-02 12:00共180分钟,还需要20分钟,再找下一条记录,2014-09-02 13:00时段用20分钟,所以结束时间为13:20
第二行a01开始时间为2014-09-05 09:00,560分钟,在#b中找到最早在2014-09-05 09:00及以后的记录,为2014-09-05 09:00,
即以2014-09-05 09:00为计划开始时间,在b表中从2014-09-05 09:00开始使用560分钟
b表2014-09-05 09:00-->2014-09-05 12:00共180分钟,还需要380分钟,
再找下一条记录,2014-09-05 13:00-->2014-09-05 18:00 共300分钟,还要80分钟,
再找下一条记录,2014-09-06 08:00-->2014-09-06 12:00 时段用80分钟,所以结束时间为09:20
------解决思路----------------------
a01,2014-09-02 08:00,300,2014-09-02 09:00,2014-09-02 13:20
a01,2014-09-05 09:00,300,2014-09-05 09:00,2014-09-06 09:20
*/
这里的300 是啥咋回事?
------解决思路----------------------
想到一个递归CTE,SQL2000 真想不到啥方法。除了游标
------解决思路----------------------
--求一高效的查询(sql2000)
有两个表#a及#b
--#a有编码,开始时间,需要的分钟数,计划开始时间,计划结束时间
--#B有编码,开始时间,结止时间(#b数据量比较大)
要求计算出#a的计划开始时间,计划结止时间
按#a编码及开始时间在#b最可以最早的可以开始时间,
然后将#a给定的分钟数,在#b中顺次扣减,计算出#a的计划结束时间
并更新到#a的fbdt,fedt
可以理解为a表给出开始时间及需要的分钟数,
在b表实际每个编码可以使用的时间分配记录,
计算出a在B可以最早的开始及结束时间
create table #a(code char(10),bdt datetime,fz int ,fbdt datetime null,fedt datetime null
create table #b(code char(10),bdt datetime,edt datetime)
--示例数据
insert into #a(code,bdt,fz)
select 'a01','2014-09-02 08:00',200
union
select 'a01','2014-09-05 09:00',560
insert into #b(code,bdt,edt)
select 'a01','2014-09-02 05:00','2014-09-02 07:00'
union
select 'a01','2014-09-02 09:00','2014-09-02 12:00'
union
select 'a01','2014-09-02 13:00','2014-09-02 17:00'
union
select 'a01','2014-09-05 06:00','2014-09-05 08:30'
union
select 'a01','2014-09-05 09:00','2014-09-05 12:00'
union
select 'a01','2014-09-05 13:00','2014-09-05 18:00'
union
select 'a01','2014-09-06 08:00','2014-09-06 12:00'
结果如下,
select code,bdt,fz,fbdt,fedt
from #ta
/*
a01,2014-09-02 08:00,300,2014-09-02 09:00,2014-09-02 13:20
a01,2014-09-05 09:00,300,2014-09-05 09:00,2014-09-06 09:20
*/
计算过程:
第一行a01开始时间为2014-09-02 08:00,200分钟,在#b中找到最早在2014-09-02 08:00及以后的记录,为2014-09-02 09:00,
即以2014-09-02 09:00为计划开始时间,在b表中从2014-09-02 09:00开始使用200分钟,
b表2014-09-02 09:00-->2014-09-02 12:00共180分钟,还需要20分钟,再找下一条记录,2014-09-02 13:00时段用20分钟,所以结束时间为13:20
第二行a01开始时间为2014-09-05 09:00,560分钟,在#b中找到最早在2014-09-05 09:00及以后的记录,为2014-09-05 09:00,
即以2014-09-05 09:00为计划开始时间,在b表中从2014-09-05 09:00开始使用560分钟
b表2014-09-05 09:00-->2014-09-05 12:00共180分钟,还需要380分钟,
再找下一条记录,2014-09-05 13:00-->2014-09-05 18:00 共300分钟,还要80分钟,
再找下一条记录,2014-09-06 08:00-->2014-09-06 12:00 时段用80分钟,所以结束时间为09:20
------解决思路----------------------
a01,2014-09-02 08:00,300,2014-09-02 09:00,2014-09-02 13:20
a01,2014-09-05 09:00,300,2014-09-05 09:00,2014-09-06 09:20
*/
这里的300 是啥咋回事?
------解决思路----------------------
想到一个递归CTE,SQL2000 真想不到啥方法。除了游标
------解决思路----------------------
WITH b AS (
SELECT code,
ROW_NUMBER() OVER (PARTITION BY code
ORDER BY bdt
) n,
bdt,
edt
FROM #b
),
a0 AS (
SELECT code,
bdt,
(SELECT MIN(n)
FROM b
WHERE #a.code = b.code
AND #a.bdt <= b.edt
) n,
fz
FROM #a
),
a AS (
SELECT a0.code,
a0.bdt,
a0.n,
a0.fz,
CASE WHEN a0.bdt <= b.bdt THEN
b.bdt
ELSE
a0.bdt
END AS fbdt
FROM a0
JOIN b
ON a0.code = b.code
AND a0.n = b.n
),
c AS (
SELECT a.code,
a.bdt,
a.n,
a.fz - DateDiff(minute,a.fbdt,b.edt) AS fz,
a.fbdt,
CASE WHEN b.edt <= DateAdd(minute,a.fz,a.fbdt) THEN