declare @tb table (id int ,name varchar(20), ddate datetime) insert into @tb (id , name , ddate) select 1,'张三','2010-3-4' union all select 2,'张三','2011-3-4' union all select 3,'张三','2012-3-4' union all select 4,'张三','2013-3-4' union all select 5,'张三','2014-3-4' union all select 6,'张三','2015-3-4' union all select 7,'李四','2010-5-1' union all select 8,'李四','2011-5-1' union all select 9,'李四','2012-5-1' union all select 10,'李四','2013-5-1' union all select 11,'李四','2014-5-1' union all select 12,'李四','2015-5-1' declare @tt table (name varchar(20), ddate varchar(7), job varchar(20)) insert into @tt (name, ddate, job) select '张三', '2010-04','助理工程师' union all select '张三', '2013-04','工程师' union all select '张三', '2015-04','高级工程师' union all select '李四', '2010-04','助理工程师' union all select '李四', '2013-04','工程师' union all select '李四', '2015-04','中级工程师' --tt 职位变动,工资应该也相应有所变化,所以想查询@tb变每个时间点职位
楼上写的好像有些问题。。。试试下面这个。。。
WITH t AS (
SELECT ROW_NUMBER() OVER(PARTITION BY name ORDER BY name,ddate) id, name,cast(ddate+'-01' as datetime) as ddate,job from @tt
)
SELECT b.*,t1.ddate,t2.ddate,t1.job FROM @tb b LEFT JOIN t t1
ON b.name=t1.name
AND b.ddate>=t1.ddate
LEFT JOIN t t2
ON t1.name=t2.name AND t2.id=t1.id+1
WHERE b.ddate < t2.ddate OR t2.ddate IS NULL
ORDER BY b.id
--2楼经验证结果正确,也有这个写法, 在此标记一下
SELECT *
FROM @tb b
CROSS APPLY (
SELECT TOP 1 job
FROM @tt t
WHERE t.name = b.name
AND CONVERT(datetime,t.ddate+'-01',120) <= b.ddate
ORDER BY ddate DESC
) a
declare @tb table (id int ,name varchar(20), ddate datetime) insert into @tb (id , name , ddate) select 1,'张三','2010-3-4' union all select 2,'张三','2011-3-4' union all select 3,'张三','2012-3-4' union all select 4,'张三','2013-3-4' union all select 5,'张三','2014-3-4' union all select 6,'张三','2015-3-4' union all select 7,'李四','2010-5-1' union all select 8,'李四','2011-5-1' union all select 9,'李四','2012-5-1' union all select 10,'李四','2013-5-1' union all select 11,'李四','2014-5-1' union all select 12,'李四','2015-5-1' declare @tt table (name varchar(20), ddate varchar(7), job varchar(20)) insert into @tt select '张三', '2010-04','助理工程师' union all select '张三', '2013-04','工程师' union all select '张三', '2015-04','高级工程师' union all select '李四', '2010-04','助理工程师' union all select '李四', '2013-04','工程师' union all select '李四', '2015-04','中级工程师' --tt 职位变动,工资应该也相应有所变化,所以想查询@tb变每个时间点职位 ;with cte as ( select a.*,b.ddate as d,b.job from @tb a left join ( select name,cast(ddate+'-01' as datetime) as ddate,job from @tt ) b on a.name=b.name and a.ddate<=b.ddate ),c1 as ( select * from cte a where not exists(select 1 from cte b where id=a.id and d<a.d) ) --处理最后一条问题 select a.id,a.name,a.ddate,max(isnull(a.d,cast(b.ddate+'-01' as datetime))),max(isnull(a.job,b.job)) from c1 a left join @tt b on a.d is null and a.name=b.name and a.ddate>cast(b.ddate+'-01' as datetime) group by a.id,a.name,a.ddate /* id name ddate ----------- -------------------- ----------------------- ----------------------- -------------------- 1 张三 2010-03-04 00:00:00.000 2010-04-01 00:00:00.000 助理工程师 2 张三 2011-03-04 00:00:00.000 2013-04-01 00:00:00.000 工程师 3 张三 2012-03-04 00:00:00.000 2013-04-01 00:00:00.000 工程师 4 张三 2013-03-04 00:00:00.000 2013-04-01 00:00:00.000 工程师 5 张三 2014-03-04 00:00:00.000 2015-04-01 00:00:00.000 高级工程师 6 张三 2015-03-04 00:00:00.000 2015-04-01 00:00:00.000 高级工程师 7 李四 2010-05-01 00:00:00.000 2013-04-01 00:00:00.000 工程师 8 李四 2011-05-01 00:00:00.000 2013-04-01 00:00:00.000 工程师 9 李四 2012-05-01 00:00:00.000 2013-04-01 00:00:00.000 工程师 10 李四 2013-05-01 00:00:00.000 2015-04-01 00:00:00.000 中级工程师 11 李四 2014-05-01 00:00:00.000 2015-04-01 00:00:00.000 中级工程师 12 李四 2015-05-01 00:00:00.000 2015-04-01 00:00:00.000 助理工程师 */