--如何得到这样一个顺序号?/*
如何根据销货事务明细表,查询到货品编码已连续多少天有出货记录,
当有日期中断时,从1开始计数
主要条件:1:任一货品一天可以有多条出货记录
2:任一货品也可多天没有一条出货记录
销货事务明细表(主要字段 货品编码 + 出货数量 + 出货日期 + 出货单价 + 出货单号)
*/create table t_tran(id int identity(1,1), --唯一行号
item_no varchar(60) null,--货品编码
sl numeric(20,4) null,--出货数量
dt datetime null,--出货日期
price numeric(20,4) null,--出货单价
invoice varchar(50) null--出货单号
)
goinsert into t_tran(item_no,sl,dt,price,invoice)
select '0001',10,'2006-08-01',50,'io0001'
union
select '0001',20,'2006-08-02',50,'io0003'
union
select '0002',5,'2006-08-01',100,'io0005'
union
select '0002',8,'2006-08-03',100,'io0008'
union
select '0002',6,'2006-08-04',100,'io0015'
union
select '0001',3,'2006-08-06',50,'io0055'
union
select '0001',16,'2006-08-07',50,'io0045'
union
select '0001',17,'2006-08-08',50,'io0019'
union
select '0001',15,'2006-08-08',50,'io0029'
union
select '0001',18,'2006-08-09',50,'io0089'
union
select '0001',10,'2006-08-10',50,'io0099'
go--根据销货事务明细表,查询到货品编码已连续多少天有出货记录,结果大致如下:(货品编码+日期+连续多少天)
--输入参数:货品编码(多个) + 日期区间(开始日期及结束日期)
--输出结果:
/*
item_no dt days
'0001' '2006-08-01' 1
'0001' '2006-08-02' 2--注:1号有出货记录,2号也有,因此连续天数为2
'0001' '2006-08-06' 1--注:3-5号0001货品没有出货,此处从1开始计数
'0001' '2006-08-07' 2
'0001' '2006-08-08' 3
'0001' '2006-08-09' 4
'0001' '2006-08-10' 5
'0002' '2006-08-01' 1
'0002' '2006-08-03' 1--注:2号0002货品没有出货,此处从1开始计数
'0002' '2006-08-04' 2
*/
如何根据销货事务明细表,查询到货品编码已连续多少天有出货记录,
当有日期中断时,从1开始计数
主要条件:1:任一货品一天可以有多条出货记录
2:任一货品也可多天没有一条出货记录
销货事务明细表(主要字段 货品编码 + 出货数量 + 出货日期 + 出货单价 + 出货单号)
*/create table t_tran(id int identity(1,1), --唯一行号
item_no varchar(60) null,--货品编码
sl numeric(20,4) null,--出货数量
dt datetime null,--出货日期
price numeric(20,4) null,--出货单价
invoice varchar(50) null--出货单号
)
goinsert into t_tran(item_no,sl,dt,price,invoice)
select '0001',10,'2006-08-01',50,'io0001'
union
select '0001',20,'2006-08-02',50,'io0003'
union
select '0002',5,'2006-08-01',100,'io0005'
union
select '0002',8,'2006-08-03',100,'io0008'
union
select '0002',6,'2006-08-04',100,'io0015'
union
select '0001',3,'2006-08-06',50,'io0055'
union
select '0001',16,'2006-08-07',50,'io0045'
union
select '0001',17,'2006-08-08',50,'io0019'
union
select '0001',15,'2006-08-08',50,'io0029'
union
select '0001',18,'2006-08-09',50,'io0089'
union
select '0001',10,'2006-08-10',50,'io0099'
go--根据销货事务明细表,查询到货品编码已连续多少天有出货记录,结果大致如下:(货品编码+日期+连续多少天)
--输入参数:货品编码(多个) + 日期区间(开始日期及结束日期)
--输出结果:
/*
item_no dt days
'0001' '2006-08-01' 1
'0001' '2006-08-02' 2--注:1号有出货记录,2号也有,因此连续天数为2
'0001' '2006-08-06' 1--注:3-5号0001货品没有出货,此处从1开始计数
'0001' '2006-08-07' 2
'0001' '2006-08-08' 3
'0001' '2006-08-09' 4
'0001' '2006-08-10' 5
'0002' '2006-08-01' 1
'0002' '2006-08-03' 1--注:2号0002货品没有出货,此处从1开始计数
'0002' '2006-08-04' 2
*/
解决方案 »
- 请问怎么加上nolock
- 一个简单的问题
- 关于smallDateTime类型字段排序的问题
- 怎么修改存储过程的所有者
- bcp导入数据到库中相关表时,怎样判断数据重复问题
- 求个SQL语句或效率稍高一点的其它解决方案,我脑子转不过弯
- select e.*,s.name as dept_name from empl as e inner join dept as d on e.deptID = d.id 问题请教
- 恢复数据库错?
- 比較菜的問題,在存儲過程中,怎樣檢測文本文件是否存在並進行讀寫,或追加內容?
- 求sql语句
- 提取表中头10条,头11-20,21-30条,31-40条数据按id降序
- 怎么取只取DateTime的年月日啊,不要后面的时分秒啊?
a.item_no,a.dt,datediff(dd,max(b.dt),a.dt)+1
from
(select
distinct b.item_no,b.dt
from
t_tran b) a,
(select
distinct c.item_no,c.dt
from
t_tran c
where
not exists(select 1 from t_tran where item_no=c.item_no and datediff(dd,c.dt,dt)=1)) d
where
a.item_no=d.item_no and a.dt>=d.dt
group by
a.item_no,a.dt
into #t
from t_tran a
group by item_no,dt
order by item_no,dt
declare @dt datetime
declare @item_no varchar(10)
declare @days int
set @days=0update #t
set @days=case when @item_no=item_no and dt=dateadd(day,1,@dt) then @days+1 else 1 end,
@item_no=item_no,@dt=dt,days=@daysselect * from #t
drop table #t
--结果
item_no dt days
------------------------------------------------------------ ------------------------------------------------------ -----------
0001 2006-08-01 00:00:00.000 1
0001 2006-08-02 00:00:00.000 2
0001 2006-08-06 00:00:00.000 1
0001 2006-08-07 00:00:00.000 2
0001 2006-08-08 00:00:00.000 3
0001 2006-08-09 00:00:00.000 4
0001 2006-08-10 00:00:00.000 5
0002 2006-08-01 00:00:00.000 1
0002 2006-08-03 00:00:00.000 1
0002 2006-08-04 00:00:00.000 2(所影响的行数为 10 行)
结果不对,主要问题在日期中断后,没有重新生成序号to:i9988
结果正确,但对下面的语句是如何执行的不太明白,是否可以讲解或指点相关资料,
其作用是否与用游标逐行一样
update #t
set @days=case when @item_no=item_no and dt=dateadd(day,1,@dt) then @days+1 else 1 end,
@item_no=item_no,@dt=dt,days=@days
update语句内部操作也是逐条进行的,总有执行的先后,这里用变量来保存了上一条的item_no和dt,用于这一条的比较,那个case语句就是计算这一条的days的,如果
item_no和上一条相同(@item_no=item_no) 而且 dt是上一条的下一天(dt=dateadd(day,1,@dt)),表示连续,那days就是上一条的days+1,否则不连续,就是1了其他的不讲了,不知道能否说清楚
from t_tran a order by item_no, dtselect max(nid) nid,item_no,dt,gid into #
from (select nid, item_no,dt,gid=case when (select count(1) from #t b where datediff(dd,b.dt,a.dt)=1 and b.item_no=a.item_no)=0 then nid else (select max(nid) from #t b where b.nid<a.nid and b.item_no=a.item_no and
(select count(1) from #t c where datediff(dd,c.dt,b.dt)=1)=0 and b.item_no=a.item_no) end from #t a) x
group by item_no,dt,gid
select item_no,dt,(select count(1) from # b where b.nid<=a.nid and b.gid=a.gid) from # a
drop table t_tran,#t,#
/*
0001 2006-08-01 00:00:00.000 1
0001 2006-08-02 00:00:00.000 2
0001 2006-08-06 00:00:00.000 1
0001 2006-08-07 00:00:00.000 2
0001 2006-08-08 00:00:00.000 3
0001 2006-08-09 00:00:00.000 4
0001 2006-08-10 00:00:00.000 5
0002 2006-08-01 00:00:00.000 1
0002 2006-08-03 00:00:00.000 1
0002 2006-08-04 00:00:00.000 2
*/
我用临时表生成标识列只是为了写语句方便。 否则写条件时要写一堆很烦琐.因为有了原表中的标识列,所以那个临时表生成的标识列我也可以用count算法算出来.至于递规查询变量,通常下用的select查询较多一点,update查询也可以用.
刚才有个贴子里问到了,刚好有人写到了,你看一下就明白了。
http://community.csdn.net/Expert/topic/4965/4965240.xml?temp=.3989527
如果同一item_no每天有多条记录,用这个:
select a.item_no,a.dt,max(datediff(dd,b.dt,a.dt)+1)
from t_tran a,t_tran b
where a.dt>=b.dt
and a.item_no=b.item_no
and not exists (select 1 from t_tran where item_no=a.item_no and dt+1 between b.dt and a.dt and dt+1 not in (select dt from t_tran where item_no=a.item_no))
group by a.item_no,a.dt
order by a.item_no,a.dt 如果同一item_no每天只有一条记录,用这个:select item_no,dt,datediff(dd,(select min(dt) from t_tran b where item_no=a.item_no and dt<=a.dt and not exists (select 1 from t_tran where item_no=a.item_no and dt+1 between b.dt and a.dt and dt+1 not in (select dt from t_tran where item_no=a.item_no))),dt)+1
from t_tran a
order by a.item_no,a.dt ---逻辑:
not exists (select 1 from t_tran where item_no=a.item_no and dt+1 between b.dt and a.dt and dt+1 not in (select dt from t_tran where item_no=a.item_no)))
select distinct item_no,dt,
datediff(day,(select max(dt) from (select item_no,dt from t_tran A where not exists(select 1 from t_tran where item_no=A.item_no and datediff(day,dt,A.dt)=1)) B where B.item_no=A.item_no and B.dt<=A.dt),dt)+1 连续天数
from t_tran A
order by item_no,dt
以前写的那些因为每条记录中的某些数据要用到,所以要那样写。而这个只是个count,所以可以用楼上各位的写法。
datediff(day,(select max(dt) from t_tran b where item_no=a.item_no and dt<=a.dt and not exists(select 1 from t_tran where item_no=b.item_no and datediff(day,dt,b.dt)=1 and dt<=b.dt)),dt)+1
from t_tran a
order by item_no,dt
(select count(1) from #t c where datediff(dd,c.dt,b.dt)=1)=0 and b.item_no=a.item_noselect max(dt) from t_tran b where item_no=a.item_no and dt<=a.dt and not exists(select 1 from t_tran where item_no=b.item_no and datediff(day,dt,b.dt)=1 and dt<=b.dt)
其实思路都是一样的.我是懒得想,从以前写的一些先进先出的查询直接改过来的,因为那里面每行要计算数值,所以要生成分组ID。
我修改一下
select
A.item_no,A.dt, datediff(day,max(B.dt),A.dt)+1 连续天数
from
t_tran A,
(select
distinct item_no,dt
from
t_tran A
where
not exists(select 1 from t_tran where item_no=A.item_no and datediff(day,dt,A.dt)=1)) B
where
A.item_no=B.item_no and A.dt>=B.dt
group by
A.item_no,A.dt
order by
A.item_no,A.dt