数据记录如下ClassID RightFlags
DataDiff 011010
DataDiff 011000
DataDiff 010111
DataDiff 110000
SysParam 100001
SysParam 101011
SysParam 101110
SysUsers 0001001
SysUsers 0001011
SysUsers 1110011
现在要通过某种运算得到这样的效果:
首先得到不重复ClassID,再者得到每个ClassID的权限位。
权限位取法如下(已ClassID为DataDiff为例):共有4个RightFlags,分别为011010、011000、010111、110000。4个长度一致并且都是由0、1组成通过运算对比得到如果第一位1取1,否则取0,后续几位类推。
因此DataDiff的RightFlags值最终应该是:111111。
SysParam的RightFlags值最终为是:101110。
SysUsers的RightFlags值最终为:1111011。最后返回的结果集是:
DataDiff 111111
SysParam 101110
SysUsers 1111011
请问如何用在SQL2008的数据下用存储过程,计算出以上的结果。
诚请各路老鸟支招
DataDiff 011010
DataDiff 011000
DataDiff 010111
DataDiff 110000
SysParam 100001
SysParam 101011
SysParam 101110
SysUsers 0001001
SysUsers 0001011
SysUsers 1110011
现在要通过某种运算得到这样的效果:
首先得到不重复ClassID,再者得到每个ClassID的权限位。
权限位取法如下(已ClassID为DataDiff为例):共有4个RightFlags,分别为011010、011000、010111、110000。4个长度一致并且都是由0、1组成通过运算对比得到如果第一位1取1,否则取0,后续几位类推。
因此DataDiff的RightFlags值最终应该是:111111。
SysParam的RightFlags值最终为是:101110。
SysUsers的RightFlags值最终为:1111011。最后返回的结果集是:
DataDiff 111111
SysParam 101110
SysUsers 1111011
请问如何用在SQL2008的数据下用存储过程,计算出以上的结果。
诚请各路老鸟支招
--用了函数!create table tb(ClassID varchar(10),RightFlags varchar(10))
insert into tb
select 'DataDiff' ,'011010' union all
select 'DataDiff' ,'011000' union all
select 'DataDiff' ,'010111' union all
select 'DataDiff' ,'110000' union all
select 'SysParam' ,'100001' union all
select 'SysParam' ,'101011' union all
select 'SysParam' ,'101110' union all
select 'SysUsers' ,'0001001' union all
select 'SysUsers' ,'0001011' union all
select 'SysUsers' ,'1110011'
gocreate function f_get(@ClassID varchar(10))
returns varchar(10)
as
begin
declare @i int
declare @j int
declare @RightFlags varchar(10)
select @i = max(len(RightFlags)) from tb where ClassID = @ClassID
set @j = 1
set @RightFlags = ''
while(@j <= @i)
begin
if exists (select 1 from tb where ClassID = @ClassID and substring(RightFlags,@j,1) = '1')
set @RightFlags = @RightFlags + '1'
else
set @RightFlags = @RightFlags + '0'
set @j = @j + 1
end
return @RightFlags
end
goselect ClassID,dbo.f_get(ClassID) as RightFlags
from tb
group by ClassIDdrop function f_get
drop table tb
/*ClassID RightFlags
---------- ----------
DataDiff 111111
SysParam 101111
SysUsers 1111011(3 行受影响)
共有4个RightFlags,分别为011010、011000、010111、110000。4个长度一致并且都是由0、1组成。
对比以上4个RightFlags,
4个RightFlags分别取第一位字符,
011010的第一位是0,011000的第一位是0,010111的第一位是0,110000的第一位1
取出的结果是0、0、0、1。这4个中有"1"的取"1",否则取"0"。这样第一位的结果是1。再取第二位:
011010的第二位是1,011000的第二位是1,010111的第二位是1,110000的第二位1
取出的结果是1、1、1、1。对比有"1"的取"1",否则取"0"。这样第二位结果是1。
再取第三位,
011010的第三位是1,011000的第三位是1,010111的第三位是0,110000的第三位0
取出的结果是1、1、0、0。对比有"1"的取"1",否则取"0"。这样第三位结果是1、…………这样最后DataDiff 的RightFlags字段值 就是 111111
max(substring(RightFlags,2,1))+
max(substring(RightFlags,3,1))+
max(substring(RightFlags,4,1))+
max(substring(RightFlags,5,1))+
max(substring(RightFlags,6,1))
from tb group by ClassID
;with cte1 as
(
select ClassID,b.number,max(substring(RightFlags,number,1)) as r
from tb a
join master..spt_values b
on b.type='P' and number between 1 and len(RightFlags)
group by classid,number
)
select classid,
RightFlags=(select ''+ltrim(r) from cte1 where classid=t.classid order by classid,number for xml path(''))
from cte1 t
group by classid
order by classid/**
classid RightFlags
---------- --------------------
DataDiff 111111
SysParam 101111
SysUsers 1111011(3 行受影响)
**/
不过RightFlags的长度是不固定的,感觉这样不是特别好。