如何 用T-Sql语句 对比表记录字符串?

madStone_l 2011-05-04 08:07:46
数据记录如下

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的数据下用存储过程,计算出以上的结果。
诚请各路老鸟支招。。。
...全文
116 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
madStone_l 2011-05-04
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 ssp2009 的回复:]
SQL code
select ClassID,max(substring(RightFlags,1,1))+
max(substring(RightFlags,2,1))+
max(substring(RightFlags,3,1))+
max(substring(RightFlags,4,1))+……
[/Quote]
效果对,谢谢先!
不过RightFlags的长度是不固定的,感觉这样不是特别好。
百年树人 2011-05-04
  • 打赏
  • 举报
回复
借小三的数据
;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 行受影响)
**/
快溜 2011-05-04
  • 打赏
  • 举报
回复
select ClassID,max(substring(RightFlags,1,1))+
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
madStone_l 2011-05-04
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 acherat 的回复:]
感觉像是二进制位或的运算!
[/Quote]
对,就是二进制位或运算。但是我用或运算写出来。。很纠结。
首先谢谢你提供的函数,结果是能达到。

如果能用二进制位或运算的话,应该效率会高许多。
madStone_l 2011-05-04
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 josy 的回复:]
通过运算对比得到如果第一位1取1,否则取0

--------
没看出你的结果是怎么算出来的,能否再说详细点?
[/Quote]
权限位取法如下(已ClassID为DataDiff为例):
共有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
AcHerat 2011-05-04
  • 打赏
  • 举报
回复
感觉像是二进制位或的运算!
AcHerat 2011-05-04
  • 打赏
  • 举报
回复

--用了函数!

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'
go

create 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
go

select ClassID,dbo.f_get(ClassID) as RightFlags
from tb
group by ClassID

drop function f_get
drop table tb


/*

ClassID RightFlags
---------- ----------
DataDiff 111111
SysParam 101111
SysUsers 1111011

(3 行受影响)
百年树人 2011-05-04
  • 打赏
  • 举报
回复
通过运算对比得到如果第一位1取1,否则取0

--------
没看出你的结果是怎么算出来的,能否再说详细点?

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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