首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

SQl 抽出四个字段 排序有关问题 ?

2013-09-17 
SQl 抽出四个字段 排序问题 ???我现在有一个表A有五个字段职工号补贴A补贴B补贴C补贴D121NULL25NULL2NULl3

SQl 抽出四个字段 排序问题 ???
我现在有一个表A  有五个字段
职工号   补贴A  补贴B  补贴C  补贴D
1       21    NULL    25    NULL
2       NULl    32     68    12
3       NULL   NULL    58     56  
4      NULL    45     NULL    NUll

我想在 想 抽出的结果是 
职工号   补贴A  补贴B  补贴C  补贴D
1       21   25  NULL  NULL
2       32   68  12  NULL
3       58   56  NULl  NULL
4       45   NULl NULL  NULL 

就是把 有值的 往前放  没值的 往后面放  求Sql 语句 ???    
   sql
[解决办法]

if OBJECT_ID('tempdb..#temp', 'u') is not null   drop table #temp;
go
create table #temp( [职工号] varchar(100), [补贴A] INT, [补贴B] INT, [补贴C] INT, [补贴D] INT);
insert #temp
select '1','21',null,'25',null union all
select '2',null,'32','68','12' union all
select '3',null,null,'58','56' union all
select '4',null,'45',null,null 

--SQL:
SELECT *
FROM
(
SELECT 职工号,xx,补贴类型=(CASE rowid WHEN 1 THEN '补贴A' WHEN 2 THEN '补贴B' WHEN 3 THEN '补贴C' WHEN 4 THEN '补贴D' END) FROM
(
select rowid=ROW_NUMBER() OVER(PARTITION BY 职工号 ORDER BY GETDATE()),职工号,xx
from #temp a
UNPIVOT
(xx FOR yy IN([补贴A],[补贴B],[补贴C],[补贴D])) b
) t
) m
PIVOT
(MAX(xx) FOR 补贴类型 IN([补贴A],[补贴B],[补贴C],[补贴D])) n


/*
职工号补贴A补贴B补贴C补贴D
12125NULLNULL
2326812NULL
35856NULLNULL
445NULLNULLNULL
*/


[解决办法]

--比较简陋的办法 应该有更好的

create   Function   Fn_SplitTab(@c   varchar(2048),@split   varchar(2))   
returns   @SplitTab   table(A   INT ,B int ,C int ,D int)   
as   
begin   
declare @i int = 1
while(charindex(@split,@c)<>0)   
begin   
if @i = 1
begin
insert   @SplitTab(A)   values   (substring(@c,1,charindex(@split,@c)-1))  
end
if @i = 2
begin
update   @SplitTab set B  = substring(@c,1,charindex(@split,@c)-1)
end
if @i = 3
begin
update   @SplitTab set C  = substring(@c,1,charindex(@split,@c)-1)
end
if @i = 4
begin
update   @SplitTab set D  = substring(@c,1,charindex(@split,@c)-1)

end
set   @c   =   stuff(@c,1,charindex(@split,@c),'')   
set @i = @i + 1
end   
return   
end   

--------------------------

declare @T table (ID int,A int,B int, C int, D int)
insert into @T
select 1,21, null, 25 ,null union all
select 2,null, 32, 68 ,12 union all
select 3,null, null, 58 ,56 union all
select 4,null, 45, null ,null union all
select 4,12, NULL, null ,null 
;WITH T as (
select  *,
case when A is not null then convert(varchar(8),A) + '
[解决办法]
' else '' end +
case when B is not null then convert(varchar(8),B) + '
[解决办法]
' else '' end +
case when C is not null then convert(varchar(8),C) + '
------解决方案--------------------


' else '' end +
case when D is not null then convert(varchar(8),D) + '
[解决办法]
' else '' end  as ABCD
from @t
)
select a.ID,b.*
from T a cross apply dbo.Fn_SplitTab(a.ABCD,'
[解决办法]
') b
/*
(5 行受影响)
ID          A           B           C           D
----------- ----------- ----------- ----------- -----------
1           21          25          NULL        NULL
2           32          68          12          NULL
3           58          56          NULL        NULL
4           45          NULL        NULL        NULL
4           12          NULL        NULL        NULL

(5 行受影响)
*/



[解决办法]

WITH a1 (id,a,b,c,d) AS
(
SELECT 1,21,NULL,25,NULL UNION ALL
SELECT 2,NULl,32,68,12 UNION ALL
SELECT 3,NULL,NULL,58,56 UNION ALL
SELECT 4,NULL,45,NULL,NULL
)
,a2 AS
(
SELECT id
,ISNULL(RTRIM(a),'')+','+ISNULL(RTRIM(b),'')+','+ISNULL(RTRIM(c),'')+','+ISNULL(RTRIM(d),'') msg
FROM a1
)
,a3 AS
(
SELECT a.id,CASE WHEN b.msg='' THEN NULL ELSE b.msg END msg
FROM
(SELECT id, msg=CONVERT(XML, '<root><v>'+replace(RTRIM(LTRIM(msg)),',','</v><v>')+'</v></root>') FROM a2) a


OUTER APPLY
(SELECT msg = C.v.value('.','NVARCHAR(MAX)') FROM a.msg.nodes('/root/v') C(v)) b
)
,a4 AS
(
SELECT *,ROW_NUMBER() OVER (PARTITION BY id ORDER BY CASE WHEN msg IS null THEN 2 ELSE 1 END) re
FROM a3
)
SELECT *
FROM a4
PIVOT (MAX(msg) FOR re IN ([1],[2],[3],[4])) b


[解决办法]

create table #tb(职工号 int,补贴A int,补贴B int,补贴C int,补贴D int)
insert into #tb
select 1,21,NULL,25,NULL
union all select 2,NULL,32,68,12
union all select 3,NULL,NULL,58,56
union all select 4,NULL,45,NULL,NULL

;with cte as 
(select 职工号,SUBSTRING(补贴,number,CHARINDEX(',',补贴+',',number)-number) as 补贴
,rn=ROW_NUMBER() over(partition by 职工号 order by getdate())
from 
(select 职工号,case when 补贴A IS null then '' else STR(补贴A)+',' end+
case when 补贴B IS null then '' else STR(补贴B)+',' end+
case when 补贴C IS null then '' else STR(补贴C)+',' end+
case when 补贴D IS null then '' else STR(补贴D)+',' end+
case when 补贴A IS null then ',' else '' end+
case when 补贴B IS null then ',' else '' end+
case when 补贴C IS null then ',' else '' end+
case when 补贴D IS null then ',' else '' end+','
as 补贴
from #tb
)a, master..spt_values 
where number >=1 and type='p'  
and number<len(补贴)  and substring(','+补贴,number,1)=','
)
select 职工号,max(case when rn=1 then 补贴 end) as 补贴A,
max(case when rn=2 then 补贴 end) as 补贴B,
max(case when rn=3 then 补贴 end) as 补贴C,
max(case when rn=4 then 补贴 end) as 补贴D
from cte 
group by 职工号


/*
职工号补贴A补贴B补贴C补贴D
1        21        25
2        32        68        12
3        58        56


4        45
*/

热点排行