求一个SQL的写法

wartim 2012-03-16 10:49:56
有一个折扣表,存储了每个月的消费卡的折扣,比如
年 月 卡类 折扣
2012 4 1 90%
2012 4 2 85%

每个月的卡类是固定的,比如都是1、2类卡
但不是每个月都有记录的,只是在要修改新折扣时才保存了修改的头一个月的记录,比如2013年2月份又去改了一次
2012 4 1 90%
2012 4 2 85%

2013 2 1 75%
2013 2 2 80%

系统从2012年1月开始算到最新日期,这时需要把所有中间间断的月份的记录补齐,补齐原则是看上一个月有没有,有就按卡类克隆上一个月的,如果没有就再往上走,如果一直没有,折扣就默认为100%,之前的就不需要补,

也就是没记录的月份代表这些折扣设置保持不变
所以最后的结果(是视图或存储过程而不是真的往表里填空缺的)应该是
2012 1 1 100%
2012 1 2 100%
2012 2 1 100%
2012 2 2 100%
2012 3 1 100%
2012 3 2 100%

2012 4 1 90%
2012 4 2 85%
2012 5 1 90%
2012 5 2 85%
2012 6 1 90%
2012 6 2 85%
2012 7 1 90%
2012 7 2 85%
2012 8 1 90%
2012 8 2 85%
2012 9 1 90%
2012 9 2 85%
2012 10 1 90%
2012 10 2 85%
2012 11 1 90%
2012 11 2 85%
2012 12 1 90%
2012 12 2 85%
2013 1 1 90%
2013 1 2 85%

2013 2 1 75%
2013 2 2 80%
...全文
126 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
dawugui 2012-03-16
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 wartim 的回复:]
引用 1 楼 vastm 的回复:
拜托,楼主提问题最好直接一些~最好把表结构,数据初始化带着,彼此都很忙的~


有一个折扣表,存储了每个月的消费卡的折扣,比如
年 月 卡类 折扣
2012 4 1 90%
2012 4 2 85%

这不就是表结构么。。。。很简单,就4个字段,年月,卡类,折扣,字段类型无所谓,怎么简单怎么设,那都int好了,那折扣就是0.9和0.85
初始……
[/Quote]写错了点,更改为如下:
create table tb(年 int,月 int,卡类 int ,折扣 varchar(10))
insert into tb values('2012', 4 ,1 ,'90%')
insert into tb values('2012', 4 ,2 ,'85%')
insert into tb values('2013', 2 ,1 ,'75%')
insert into tb values('2013', 2 ,2 ,'80%')
go

declare @sdate datetime
declare @edate datetime
set @sdate = (select ltrim(min(年)) from tb) + '-01-01'
set @edate = (select max(ltrim(年) + '-' + right('0'+ltrim(月),2)) from tb) + '-01'

select datepart(yy,t1.dt) 年,
datepart(mm,t1.dt) 月,
t1.卡类,
折扣 = (case when datepart(yy,t1.dt) = t2.年 and datepart(mm,t1.dt) = t2.月 and t1.卡类 = t2.卡类 then t2.折扣
else isnull((select top 1 折扣 from tb where 卡类 = t1.卡类 and (ltrim(年) + '-' + right('0'+ltrim(月),2)) < convert(varchar(7),t1.dt,120) order by (ltrim(年) + '-' + right('0'+ltrim(月),2)) desc),'100%') end ) from
(
select m.dt , n.卡类 from
(
select
dateadd(mm,num,@sdate) dt
from
(select isnull((select count(1) from sysobjects where id<t.id),0) as num from sysobjects t) a
where
dateadd(mm,num,@sdate)<=@edate
) m , (select distinct 卡类 from tb) n
) t1 left join tb t2
on datepart(yy,t1.dt) = t2.年 and datepart(mm,t1.dt) = t2.月 and t1.卡类 = t2.卡类
order by datepart(yy,t1.dt),datepart(mm,t1.dt),t1.卡类

drop table tb

/*
年 月 卡类 折扣
----------- ----------- ----------- ----------
2012 1 1 100%
2012 1 2 100%
2012 2 1 100%
2012 2 2 100%
2012 3 1 100%
2012 3 2 100%
2012 4 1 90%
2012 4 2 85%
2012 5 1 90%
2012 5 2 85%
2012 6 1 90%
2012 6 2 85%
2012 7 1 90%
2012 7 2 85%
2012 8 1 90%
2012 8 2 85%
2012 9 1 90%
2012 9 2 85%
2012 10 1 90%
2012 10 2 85%
2012 11 1 90%
2012 11 2 85%
2012 12 1 90%
2012 12 2 85%
2013 1 1 90%
2013 1 2 85%
2013 2 1 75%
2013 2 2 80%

(所影响的行数为 28 行)


*/

dawugui 2012-03-16
  • 打赏
  • 举报
回复
create table tb(年 int,月 int,卡类 int ,折扣 varchar(10))
insert into tb values('2012', 4 ,1 ,'90%')
insert into tb values('2012', 4 ,2 ,'85%')
insert into tb values('2013', 2 ,1 ,'75%')
insert into tb values('2013', 2 ,2 ,'80%')
go

declare @sdate datetime
declare @edate datetime
set @sdate = (select ltrim(min(年)) from tb) + '-01-01'
set @edate = (select max(ltrim(年) + '-' + right('0'+ltrim(月),2)) from tb) + '-01'

select datepart(yy,t1.dt) 年,
datepart(mm,t1.dt) 月,
t1.卡类,
折扣 = (case when datepart(yy,t1.dt) = t2.年 and datepart(mm,t1.dt) = t2.月 and t1.卡类 = t2.卡类 then t2.折扣
else isnull((select top 1 折扣 from tb where (ltrim(年) + '-' + right('0'+ltrim(月),2)) < convert(varchar(7),t1.dt,120) order by (ltrim(年) + '-' + right('0'+ltrim(月),2)) desc),'100%') end ) from
(
select m.dt , n.卡类 from
(
select
dateadd(mm,num,@sdate) dt
from
(select isnull((select count(1) from sysobjects where id<t.id),0) as num from sysobjects t) a
where
dateadd(mm,num,@sdate)<=@edate
) m , (select distinct 卡类 from tb) n
) t1 left join tb t2
on datepart(yy,t1.dt) = t2.年 and datepart(mm,t1.dt) = t2.月 and t1.卡类 = t2.卡类
order by datepart(yy,t1.dt),datepart(mm,t1.dt),t1.卡类

drop table tb

/*
年 月 卡类 折扣
----------- ----------- ----------- ----------
2012 1 1 100%
2012 1 2 100%
2012 2 1 100%
2012 2 2 100%
2012 3 1 100%
2012 3 2 100%
2012 4 1 90%
2012 4 2 85%
2012 5 1 85%
2012 5 2 85%
2012 6 1 85%
2012 6 2 85%
2012 7 1 85%
2012 7 2 85%
2012 8 1 85%
2012 8 2 85%
2012 9 1 85%
2012 9 2 85%
2012 10 1 85%
2012 10 2 85%
2012 11 1 85%
2012 11 2 85%
2012 12 1 85%
2012 12 2 85%
2013 1 1 85%
2013 1 2 85%
2013 2 1 75%
2013 2 2 80%

(所影响的行数为 28 行)
*/
wartim 2012-03-16
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 vastm 的回复:]
拜托,楼主提问题最好直接一些~最好把表结构,数据初始化带着,彼此都很忙的~
[/Quote]

有一个折扣表,存储了每个月的消费卡的折扣,比如
年 月 卡类 折扣
2012 4 1 90%
2012 4 2 85%

这不就是表结构么。。。。很简单,就4个字段,年月,卡类,折扣,字段类型无所谓,怎么简单怎么设,那都int好了,那折扣就是0.9和0.85
初始化?是默认值把,但我又不是真的往表里去填,而是视图或存储过程出结果,默认值没用

主要是逻辑有点复杂,其实如果没有不用分卡类,一个月就一条记录,我已经写出来了,但加上补齐的时候需要按卡类去匹配就麻烦了

比如更复杂点的例子就是需要补3段

2012 4 1 90%
2012 4 2 85%

2013 2 1 75%
2013 2 2 80%

2014 5 1 50%
2014 5 2 60%
夜予 2012-03-16
  • 打赏
  • 举报
回复
APHY 2012-03-16
  • 打赏
  • 举报
回复
拜托,楼主提问题最好直接一些~最好把表结构,数据初始化带着,彼此都很忙的~

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧