有表如下:
create table #tmptb
(Sno int,ONo int,Upd_date datetime,UserName varchar(50),Val int)
insert into #tmptb values (1,1,'2015/05/04','test01',10);
insert into #tmptb values (1,1,'2015/05/05','test01',20);
insert into #tmptb values (1,1,'2015/05/10','test01',50);
insert into #tmptb values (2,1,'2015/05/05','ss02',0);
insert into #tmptb values (2,2,'2015/05/06','xx03',20);
insert into #tmptb values (1,1,'2015/05/08','test01',70);
insert into #tmptb values (2,2,'2015/05/14','xx03',80);
要求处理成:
Sno ONo week1_val week2_val week3_val week4_val
1 1 70 50
2 1 0
2 2 20 80
规则如下:
时间取每周最大工作日,即从周五开始取,若没有数据则取周四,依此类推(每周只要取一个就可以了),填入相应的week中。
------解决思路----------------------
可以使用coalesce取第一个非null数值。
但是你的要求不太懂,还需要按照日期排年度周数?
------解决思路----------------------
5月1号算5月的第几周
------解决思路----------------------
SET DATEFIRST 7--令本次会话 周日为一周的第一天--一般情况也是,为了防不是的情况
SELECT Sno,ONo
,MAX(CASE WHEN WeekDate='2015-04-26' THEN Val END)week1_val
,MAX(CASE WHEN WeekDate='2015-05-03' THEN Val END)week2_val
,MAX(CASE WHEN WeekDate='2015-05-10' THEN Val END)week3_val
,MAX(CASE WHEN WeekDate='2015-05-17' THEN Val END)week4_val
,MAX(CASE WHEN WeekDate='2015-05-24' THEN Val END)week5_val
,MAX(CASE WHEN WeekDate='2015-05-31' THEN Val END)week6_val
FROM(
SELECT Sno,ONo,Upd_date,UserName,Val
,DATEADD(DAY,1-DATEPART(WEEKDAY,CONVERT(VARCHAR(10),Upd_date,120)),Upd_date)WeekDate
,ROW_NUMBER()OVER(PARTITION BY Sno,ONo
,DATEADD(DAY,1-DATEPART(WEEKDAY,CONVERT(VARCHAR(10),Upd_date,120)),Upd_date)
ORDER BY Upd_date DESC)RN
FROM #tmptb
WHERE Upd_date>='2015-05-01'AND Upd_date<'2015-06-01'--只取5月的数据
)T
WHERE RN=1
GROUP BY Sno,ONo
--如果你的数据精确到天,以上查询有些地方可以精简一下
--以上查询还可以改成动态查询
------解决思路----------------------
--动态这段是查那个月的周日
DECLARE @SQL VARCHAR(MAX)
DECLARE @StartDate DATETIME,@EndDate DATETIME,@TempDate DATETIME
SET @StartDate='2015-05-01'--查五月
SET @EndDate=DATEADD(MONTH,1,@StartDate)
SET @TempDate=DATEADD(DAY,1-DATEPART(WEEKDAY,CONVERT(VARCHAR(10),@StartDate,120)),@StartDate)
SET @SQL='SET DATEFIRST 7;SELECT Sno,ONo'
SELECT @SQL=@SQL+',MAX(CASE WHEN WeekDate='''+WeekDate+''' THEN Val END)[week'+RN+'_val]'
FROM(
SELECT CONVERT(VARCHAR(10),DATEADD(WEEK,number,@TempDate),120)WeekDate
,CAST(ROW_NUMBER()OVER(ORDER BY number)AS VARCHAR)RN
FROM master..spt_values
WHERE type='P'AND DATEADD(WEEK,number,@TempDate)<@EndDate
)T
SET @SQL=@SQL+'FROM(
SELECT Sno,ONo,Upd_date,UserName,Val
,DATEADD(DAY,1-DATEPART(WEEKDAY,CONVERT(VARCHAR(10),Upd_date,120)),Upd_date)WeekDate
,ROW_NUMBER()OVER(PARTITION BY Sno,ONo
,DATEADD(DAY,1-DATEPART(WEEKDAY,CONVERT(VARCHAR(10),Upd_date,120)),Upd_date)
ORDER BY Upd_date DESC)RN
FROM #tmptb
WHERE Upd_date>='''+CONVERT(VARCHAR(10),@StartDate,120)+'''AND Upd_date<'''+CONVERT(VARCHAR(10),@EndDate,120)+'''
)T
WHERE RN=1
GROUP BY Sno,ONo'
--PRINT @SQL
EXEC(@SQL)
DECLARE @StartDate DATETIME,@EndDate DATETIME,@TempDate DATETIME
SET @StartDate='2015-05-01'--查五月
SET @EndDate=DATEADD(MONTH,1,@StartDate)
SET @TempDate=DATEADD(DAY,1-DATEPART(WEEKDAY,CONVERT(VARCHAR(10),@StartDate,120)),@StartDate)
SELECT CONVERT(VARCHAR(10),DATEADD(WEEK,number,@TempDate),120)WeekDate
FROM master..spt_values
WHERE type='P'AND DATEADD(WEEK,number,@TempDate)<@EndDate