sql 列转行

sql 列转行,第1张

CREATE TABLE T1(A NUMBER,

b NUMBER,

c NUMBER,

d NUMBER,

e NUMBER);

insert into t1 values(1,2,3,4,5);

select from t1;

select decode(A,1,'A',null) KEY ,decode(A,1,1,null) VALUE

from t1

union all

select decode(B,2,'B',null),decode(B,2,2,null)

from t1

union all

select decode(C,3,'C',null),decode(C,3,3,null)

from t1

union all

select decode(D,4,'D',null),decode(D,4,4,null)

from t1

union all

select decode(E,5,'E',null),decode(E,5,5,null)

from t1;

我给你一个思路如果假设你的rolename只有三个角色

我就不管你前面的结果是怎么查出来的,你就以你前面结果为基本进行查询

with a1 as (

select row_number() over(partition by name order by type) seq,

ausername,

aloginid,

substr(aorgcode,1,6) zq,

aorgcode,

auserstatus,

amobile,

crolename from s_u_user a

left join s_u_user_to_role b on aid=buserid

left join s_u_role c on broleid=cid

where 1 = 1 and aorgcode like '442028%' and aid in (select userid from s_u_user_to_role where substr(roleid,1,9) like 'sbyw_role%')

select username,loginid,zq,orgcode,userstatus,mobile,

case (select count() from a1 b1 where b1name=a1name)

when 1 then (select rolename from a1 b1 where b1name=a1name)

when 2 then (select rolename from a1 b1

here b1name=a1name and seq =1)||','||

(select type from a1 b1

where b1name=a1name and seq =2)

ELSE '市局管理员,分局专员,社区业务员' END rolename

from a1 group by username,loginid,zq,orgcode,userstatus,mobile;

为了这个我也想了很长时间了,期待采纳

先将varchar2转换为clob再转换为blob。

>

希望能解决你的问题。

--准备数据

create table a(bh number, sj date, sl number);

create table b(bh number, zj blob);

insert into a values(1001, sysdate, 30);

insert into a values(1002, sysdate, 31);

insert into a values(1001, sysdate, 32);

insert into a values(1003, sysdate, 34);

insert into a values(1003, sysdate, 35);

insert into a values(1004, sysdate, 36);

insert into a values(1004, sysdate, 38);

insert into a values(1005, sysdate, 23);

insert into a values(1005, sysdate, 30);

insert into a values(1006, sysdate, 35);

insert into a values(1006, sysdate, 30);

insert into a values(1001, sysdate, 30);

--这个方法不知道能否解决你这个4k限制的问题

create or replace procedure insert_b is

  cursor a_cursor is select  from a order by bh;

  a_record a%rowtype;

  temp_bh abh%type := 0;

  temp_zj varchar2(32767);

begin

  open a_cursor;

  loop

    fetch a_cursor into a_record;

    --插入最后的一条记录

    if a_cursor%notfound then

      insert into b values(temp_bh, c2b(to_clob(temp_zj)));

      exit;

    end if;

    if temp_bh != a_recordbh then

      --插入上一条的记录值

      if temp_bh != 0 then

        insert into b values(temp_bh, c2b(to_clob(temp_zj)));

      end if;

      temp_bh := a_recordbh;

      --temp_zj := concat(concat(concat(concat(concat(concat('编号:', a_recordbh), ',时间:'), to_char(a_recordsj, 'yyyy-mm-dd')), ',数量:'), a_recordsl), ';');

      temp_zj := '编号:' || a_recordbh || ',时间:' || to_char(a_recordsj, 'yyyy-mm-dd') || ',数量:' || a_recordsl || ';';

    elsif temp_bh = a_recordbh then

      --temp_zj := concat(concat(concat(concat(concat(temp_zj, '时间:'), to_char(a_recordsj, 'yyyy-mm-dd')), ',数量:'), a_recordsl), ';');

      temp_zj := temp_zj || '时间:' || to_char(a_recordsj, 'yyyy-mm-dd') || ',数量:' || a_recordsl || ';';

    end if;

  end loop;

  close a_cursor;

end;

/

--了解了下listagg函数,这个比较简洁,不知道会不会出现你所说的4k限制问题。由你这个问题也让我学到了11g的新函数

create or replace procedure insert_b is

  cursor a_cursor is

    select bh,

           '编号:' || bh || ',' ||

           listagg('时间:' || to_char(sj, 'yyyy-mm-dd') || ',数量:' || sl,

                   ';') within group(order by bh) || '。' as res

      from a

     group by bh;

  v_bh  number;

  v_res varchar2(32767);

begin

  open a_cursor;

  loop

    fetch a_cursor

      into v_bh, v_res;

    exit when a_cursor%notfound;

    --insert into b values (v_bh, c2b(to_clob(v_res)));

    insert into b values(v_bh, to_blob(rawtohex(v_res)));

  end loop;

  close a_cursor;

end;

/

--更新数据

begin

  insert_b;

end;

/

--查询结果

select bh, to_char(b2c(zj)) from b;

--将clob类型转换为blob类型(二进制转换)

create or replace function c2b(src clob default empty_clob()) return blob is

  dest          blob;

  src_len       number := dbms_lobgetlength(src);

  dest_offset   number := 1;

  src_offset    number := 1;

  amount_c      integer := dbms_loblobmaxsize;

  blob_csid     number := dbms_lobdefault_csid;

  lang_ctx      integer := dbms_lobdefault_lang_ctx;

  warning       integer;

begin

  if src_len > 0 then

    --将dest建立在用户的临时表空间中,true表示将dest读到缓冲区。此处相当于初始化dest

    dbms_lobcreatetemporary(dest, true);

    --以readwrite模式打开dest

    dbms_lobopen(dest, dbms_loblob_readwrite);

    --读取src,转换字符数据为特定字符集格式,并将转换后的数据写入dest中

    dbms_lobconverttoblob(dest,         --目标blob

                           src,          --源clob

                           amount_c,     --指定要转换的字节数

                           dest_offset,  --指定目标lob的偏移位置(字节或字符)

                           src_offset,   --指定源lob的偏移位置(字节或字符)

                           blob_csid,    --指定字符集标识号

                           lang_ctx,     --指定语言上下文

                           warning);     --存放警告信息

  else

    select empty_blob() into dest from dual;

  end if;

  return dest;

end c2b;

/

                           

--将blob类型转换为clob类型

--varchar2类型可直接转换为clob类型

create or replace function b2c(src blob) return clob is

  dest varchar2(32767);

  temp varchar2(32767);

  v_start pls_integer := 1;

  v_buffer pls_integer := 4000;

begin

  if dbms_lobgetlength(src) is null then

    return '';

  end if;

  dest := '';

  for i in 1ceil(dbms_lobgetlength(src) / v_buffer) loop

    --当转换出来的字符串乱码时,可尝试使用注释掉的函数

    --temp := utl_rawcast_to_varchar2(utl_rawconvert(dbms_lobsubstr(src, v_buffer, v_start), 'SIMPLIFIED CHINESE_CHINAZHS16GBK', 'AMERICAN_THE NETHERLANDSUTF8'));

    temp := utl_rawcast_to_varchar2(dbms_lobsubstr(src, v_buffer, v_start));

    dest := dest || temp;

    v_start := v_start + v_buffer;

  end loop;

  return dest;

end b2c;

/

create table test13

( user1 number(8),

user2 number(8),

user3 number(8)

)

select 'user1' as UserName,user1 as count from test13

union all

select 'user2' as UserName,user2 as count from test13

union all

select 'user3' as UserName,user3 as count from test13;

以上SQL语句在Oracle11gR2中测试通过,采用通用SQL语法,在其他数据库中通用可以使用

第一:你的时间维度表基本没有意义,微软SSIS中心认为时间维度至少由日期构成主键。可以认为是最小基本业务颗粒。

来个Sample,更复杂的在我空间里。但是道理是一样的。都是借助动态SQL和一些函数。

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

/

作者:Edwin

数据库:SQL SERVER 2005+

作用:指定时间区间的自然周有几天,如果垮年度,由外围验证

Version 10

Copyright (c) 2015, SQL SERVER 2008

/

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

/参数设定区域,参数为开始时间和结束时间/

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

declare @FDate DateTime set @FDate = '2014-09-01 00:00:00000'

declare @Edate DateTime set @Edate = '2015-01-01 00:00:00000'

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

/SQL主体/

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

declare @WeekHeader nvarchar(max)

select @WeekHeader = coalesce(@WeekHeader+',['+cast(WeekOfYear as varchar)+']','['+cast(WeekOfYear as varchar)+ ']')

from 

(

 select WeekOfYear from ComnCalendar where DatePerDay>=@FDate and DatePerDay<@Edate group by WeekOfYear 

) M

declare @PivotSQL nvarchar(max) set @PivotSQL=N'

select

Year as 年份,'+@WeekHeader+'

from

(

    select [Year],WeekOfYear,DatePerDay from [DT_WareHouse][Comn][Calendar] where DatePerDay>=@FDate and DatePerDay<@Edate

) M

pivot

(

  count(DatePerDay) for [WeekOfYear] in('+@WeekHeader+')

) PVT'

exec sp_executesql @PivotSQL,N'@FDate datetime,@Edate datetime',@FDate,@Edate

执行结果:

在看一下时间维度表:

至于PVT标题别名问题,这个可以在时间维度表中创建字符串类型的第几周等样式的列来完成。

这种方式比较简单。

或是

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

/

作者:Edwin

数据库:SQL SERVER 2005+

作用:指定时间区间的自然周销售,统计周期为某一年,如果垮年度,由外围验证

Version 10

Copyright (c) 2015, SQL SERVER 2008

/

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

/参数设定区域,参数为开始时间和结束时间/

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

declare @FDate DateTime set @FDate = '2014-09-01 00:00:00000'

declare @Edate DateTime set @Edate = '2015-01-01 00:00:00000'

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

/SQL主体/

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

declare @WeekHeader nvarchar(max)

select @WeekHeader = coalesce(@WeekHeader+',['+cast(WeekOfYear as varchar)+']','['+cast(WeekOfYear as varchar)+ ']')

from 

(

 select ('第'+cast(WeekOfYear as varchar)+'周') as WeekOfYear from ComnCalendar where DatePerDay>=@FDate and DatePerDay<@Edate group by WeekOfYear 

) M

declare @PivotSQL nvarchar(max) set @PivotSQL=N'

select

Year as 年份,'+@WeekHeader+'

from

(

select [Year],(''第''+cast(WeekOfYear as varchar)+''周'') as WeekOfYear,DatePerDay from [DT_WareHouse][Comn][Calendar] where DatePerDay>=@FDate and DatePerDay<@Edate

) M

pivot

(

  count(DatePerDay) for [WeekOfYear] in('+@WeekHeader+')

) PVT'

exec sp_executesql @PivotSQL,N'@FDate datetime,@Edate datetime',@FDate,@Edate

结果:

以上就是关于sql 列转行全部的内容,包括:sql 列转行、DB2数据库问题,列转行问题、关于ORACLE列转行的问题等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/sjk/9781698.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存