求一个字符串归并的sql写法

lucky_2005 2012-02-21 01:36:25
如题,要求如下:

表中有字段right类型为char(10),内容为10位0或者1,求如何合并多条记录间的字符串。

例:
A记录,right为 ‘1100001111’
B记录,right为 ‘1100101111’
B记录,right为 ‘1101001111’

要求达到的效果right为‘1101101111’请大家帮忙了

...全文
208 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
hupeng213 2012-02-21
  • 打赏
  • 举报
回复
每行记录逐位拆分,然后所有记录的每一位做1和0的与算法,得到结果再合并显示
minitoy 2012-02-21
  • 打赏
  • 举报
回复
SQL> create table t_test
2 (id number,
3 status varchar2(100));

Table created

SQL>
SQL> insert into t_test
2 values(1,'1100001111');

1 row inserted

SQL>
SQL> insert into t_test
2 values(1,'1100101111');

1 row inserted

SQL>
SQL> insert into t_test
2 values(1,'1101001111');

1 row inserted

SQL> commit;

Commit complete

SQL> select id,func_bit_or(status) from t_test group by id;

ID FUNC_BIT_OR(STATUS)
---------- --------------------------------------------------------------------------------
1 1101101111

SQL>
minitoy 2012-02-21
  • 打赏
  • 举报
回复
create or replace type type_bit_or as object (
--聚合函数的实质就是一个对象
string_to_bit_or varchar2(4000),
static function ODCIAggregateInitialize(v_self in out type_bit_or) return number,
--对象初始化
member function ODCIAggregateIterate(self in out type_bit_or, value in varchar2) return number,
--聚合函数的迭代方法(这是最重要的方法)
member function ODCIAggregateMerge(self in out type_bit_or, v_next in type_bit_or) return number,
--当查询语句并行运行时,才会使用该方法,可将多个并行运行的查询结果聚合

member function ODCIAggregateTerminate(self in type_bit_or, return_value out varchar2 ,v_flags in number) return number
--终止聚集函数的处理,返回聚集函数处理的结果.
) ;

create or replace type body type_bit_or is
static function ODCIAggregateInitialize(v_self in out type_bit_or) return number is
begin
v_self := type_bit_or(null);
return ODCICONST.Success;
end;
member function ODCIAggregateIterate(self in out type_bit_or, value in varchar2) return number is
begin
/* 连接,解决逗号分隔第一个字母是逗号的问题 */
if not self.string_to_bit_or is null then
self.string_to_bit_or := utl_raw.bit_or(self.string_to_bit_or , value);
else
self.string_to_bit_or := value;
end if;

return ODCICONST.Success;
end;
member function ODCIAggregateMerge(self in out type_bit_or, v_next in type_bit_or) return number is
begin
/* 连接 */
self.string_to_bit_or := utl_raw.bit_or(self.string_to_bit_or, v_next.string_to_bit_or);
return ODCICONST.Success;
end;
member function ODCIAggregateTerminate(self in type_bit_or, return_value out varchar2 ,v_flags in number) return number is
begin
return_value:= self.string_to_bit_or;
return ODCICONST.Success;
end;
end;



create or replace function func_bit_or(value Varchar2) return Varchar2
parallel_enable aggregate using type_bit_or;

minitoy 2012-02-21
  • 打赏
  • 举报
回复
可以用utl_raw.bit_or自己实现一个分组函数
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 lucky_2005 的回复:]

引用 8 楼 hj_daxian 的回复:
case when substr(lpad(to_char(sum(to_number( rights))), 10, '0'),1,1) >= '1' then '1'else '0' end

这样应该简便点吧 case when sum(substr(rights,1,1)) > 0 then 1 else 0


string型不能……
[/Quote]

可以的 oracle会自动转换类型 你可以试下
xpingping 2012-02-21
  • 打赏
  • 举报
回复
with tb as (select  '1100001111' right from dual 
union all select '1100101111' from dual union all
select '1101001111' from dual
)
select replace(wm_concat(case when substrb(sum_right,rownum,1)=0 and
substrb(sum_right,10+ rownum,1)=0 and substrb(sum_right,20+rownum,1)=0
then 0 else 1 end),',','')
from(select replace(wm_concat(right),',','') sum_right from tb ) connect by rownum<=10
lucky_2005 2012-02-21
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 hj_daxian 的回复:]
case when substr(lpad(to_char(sum(to_number( rights))), 10, '0'),1,1) >= '1' then '1'else '0' end

这样应该简便点吧 case when sum(substr(rights,1,1)) > 0 then 1 else 0
[/Quote]

string型不能sum的吧
  • 打赏
  • 举报
回复
case when substr(lpad(to_char(sum(to_number( rights))), 10, '0'),1,1) >= '1' then '1'else '0' end

这样应该简便点吧 case when sum(substr(rights,1,1)) > 0 then 1 else 0
lucky_2005 2012-02-21
  • 打赏
  • 举报
回复
以上是我目前在用的办法,虽然办法笨笨,不过总算是能实现功能,呵呵
lucky_2005 2012-02-21
  • 打赏
  • 举报
回复
这个是一个char(10)的字符串,由10位0或1组成。需要的是在sql里把多条记录中的这些值归并,每一位有1就是1,全0就是0。现在是用的最笨的办法来写了一个,呵呵。希望大家有更好的办法。

select
case when substr(lpad(to_char(sum(to_number( rights))), 10, '0'),1,1) >= '1' then '1'else '0' end ||
case when substr(lpad(to_char(sum(to_number( rights))), 10, '0'),2,1) >= '1' then '1'else '0' end ||
case when substr(lpad(to_char(sum(to_number( rights))), 10, '0'),3,1) >= '1' then '1'else '0' end ||
case when substr(lpad(to_char(sum(to_number( rights))), 10, '0'),4,1) >= '1' then '1'else '0' end ||
case when substr(lpad(to_char(sum(to_number( rights))), 10, '0'),5,1) >= '1' then '1'else '0' end ||
case when substr(lpad(to_char(sum(to_number( rights))), 10, '0'),6,1) >= '1' then '1'else '0' end ||
case when substr(lpad(to_char(sum(to_number( rights))), 10, '0'),7,1) >= '1' then '1'else '0' end ||
case when substr(lpad(to_char(sum(to_number( rights))), 10, '0'),8,1) >= '1' then '1'else '0' end ||
case when substr(lpad(to_char(sum(to_number( rights))), 10, '0'),9,1) >= '1' then '1'else '0' end ||
case when substr(lpad(to_char(sum(to_number( rights))), 10, '0'),10,1) >= '1' then '1'else '0' end rights
from tablename
xpingping 2012-02-21
  • 打赏
  • 举报
回复
错了……误解楼主的意思……
xpingping 2012-02-21
  • 打赏
  • 举报
回复
思路:
先写了下面2个函数;
现将right转换成10进制数 FUNC_TO_NUMBER(right)即可,
然后做你的运算(比如存入变量 result) ,最后将运算结果FUNC_TO_CHAR(result)转换成Varchar
2进制->10进制
create or replace function FUNC_TO_NUMBER(STR in varchar2) return number is
result number(10) := 0;
len number(20);
begin
len := lengthb(STR);
for i in 1 .. len
loop
result := result + substrb(STR, i, 1) * power(2, i - 1);
end loop;
return result;
end FUNC_TO_NUMBER;

10进制->2进制
create or replace function FUNC_TO_CHAR(NUM number) return varchar2 is
result varchar2(10);
num_mod number(1);
num_all number(10);

begin
num_all := NUM;
while (num_all != 0)
loop
num_mod := mod(num_all, 2);
num_all := trunc(num_all / 2);
result := num_mod || result;
end loop;
return result;
end FUNC_TO_CHAR;
mingchaoyan 2012-02-21
  • 打赏
  • 举报
回复
看来是做位或运算了;

oracle 位与运算时有现成函数的,但入参是10进制的
网上可以搜到许多 进制转换的 函数

或者 按照ls说的 自己分割然后合并

看看有没有高手提出更好的解决方案
  • 打赏
  • 举报
回复
貌似也只有分割数据计算合并才行了?暂时想不到好方法了
  • 打赏
  • 举报
回复
要按记录分组合并还是直接合并right?

效果是
   
right
A 1100001111
B 1101101111
--还是
right
1101101111

17,086

社区成员

发帖
与我相关
我的任务
社区描述
Oracle开发相关技术讨论
社区管理员
  • 开发
  • Lucifer三思而后行
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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