Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1355653
  • 博文数量: 416
  • 博客积分: 13005
  • 博客等级: 上将
  • 技术积分: 3297
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-05 16:26
文章分类

全部博文(416)

文章存档

2014年(1)

2013年(4)

2012年(46)

2011年(64)

2010年(12)

2009年(4)

2008年(40)

2007年(187)

2006年(58)

分类: 数据库开发技术

2007-03-27 09:36:03

最近有好多朋友问关于行列转换的问题
所以我将他总结一下,并加以实例,希望对大家有帮助


[code]
                             行列转换实例
表ttt有三个字段
seq  --序列
jcxm --检查项目
zhi  --值

数据分别如下:
seq   jcxm       zhi
-------      --------          --------
11     1    0.50
11     2    0.21
11     3    0.25
12     1    0.24
12     2    0.30
12     3    0.22                             

实现功能
创建视图时移动行值为列值


create view v_view1
as
select seq,
       sum(decode(jcxm,1, zhi)) 检测项目1,
       sum(decode(jcxm,2, zhi)) 检测项目2,
       sum(decode(jcxm,3, zhi)) 检测项目3
from ttt
group by seq;

序号 检测项目1  检测项目2  检测项目3
11     0.50    0.21     0.25
12     0.24    0.30     0.22



技巧:
用THEN中的0和1来进行统计(SUM)

jcxm   zhi
----   ----
a           1
b           1
a           3
d           2
e           4
f           5
a           5
d           3
d           6
b           5
c           4
b           3
求他的zhi既是1,也是3,也是5的jcxm
方法一
select jcxm
from ttt
group by jcxm
having sum(decode(zhi,1,-1,3,-1,5,-1,0)) = -3
方法二
select jcxm from ttt
group by jcxm having (sign(sum(decode(zhi,1,-1,0)))+
sign(sum(decode(zhi,3,-1,0)))+sign(sum(decode(zhi,5,-1,0)))<=-3);

----------
a
b
说明:
sign()函数根据某个值是0、正数还是负数,分别返回0、1、-1
所以可以用sign和decode来完成比较字段大小来区某个字段
select decode(sign(字段1-字段2),-1,字段3,字段4) from dual;

sign是一个对于写分析SQL有很强大的功能
下面我对sign进行一些总结:
但属性student取0和1以外的值,或者student取两个以上的标法值,问题就不会这么简单了
解决办法就是特征函数(abs(),sign())

常用的特征算法
[A=B]=1-abs(sign(A-B))
[A!=B]=abs(sign(A-B))
[A[A<=B]=sign(1-sign(A-B))
[A>B]=1-sign(1-sign(A-B))
[A>=B]=sign(1+sign(A-B)))
[NOTα]=1-d [α]
[αANDb ]=d [α]*d [b ] (6)
[αOR b ]=sign(d [α]+d [b ])

例如:
AA<=B                         Decode( Sign(A-B), 1, 0, 1 )         
A>B                         Decode( Sign(A-B), 1, 1, 0 )         
A>=B                         Decode( Sign(A-B), -1, 0, 1 )         
A=B                         Decode( A, B, 1, 0 )         
A between B and C      Decode( Sign(A-B), -1, 0, Decode(Sign(A-C), 1, 0, 1 ))         
A is null                       Decode(A,null,1,0)         
A is not null                 Decode(A,null,0,1)         A in (B1,B2,...,Bn)  Decode(A,B1,1,B2,1,...,Bn,1,0)         
nor LogA                    Decode( LogA, 0, 1, 0 )              (1-Sign(LogA))
LogA and LogB            LogA * LogB
LogA or LogB              LogA + LogB
LogA xor LogB            Decode(Sign(LogA),Sign(LogB),0,1)   
Mod(Sign(LogA),Sign(LogB),2


>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

另外一个关于成绩的分析例子

SELECT
SUM(CASE WHEN cj <60 THEN 1 ELSE 0 END) as "not passed",
SUM(CASE WHEN cj BETWEEN 60 AND 79 THEN 1 ELSE 0 END) as "passed",
SUM(CASE WHEN cj BETWEEN 80 AND 89 THEN 1 ELSE 0 END) as "good",
SUM(CASE WHEN cj >=90 THEN 1 ELSE 0 END) as "Excellent"
FROM cjtable;

decode用法2
表、视图结构转化
现有一个商品销售表sale,表结构为:
month    char(6)      --月份
sell    number(10,2)    --月销售金额

现有数据为:
200001  1000
200002  1100
200003  1200
200004  1300
200005  1400
200006  1500
200007  1600
200101  1100
200202  1200
200301  1300

想要转化为以下结构的数据:
year   char(4)          --年份
------------   ---------------------         -------------------
month1  number(10,2)   --1月销售金额
month2  number(10,2)   --2月销售金额
month3  number(10,2)   --3月销售金额
month4  number(10,2)   --4月销售金额
month5  number(10,2)   --5月销售金额
month6  number(10,2)   --6月销售金额
month7  number(10,2)   --7月销售金额
month8  number(10,2)   --8月销售金额
month9  number(10,2)   --9月销售金额
month10  number(10,2)     --10月销售金额
month11  number(10,2)     --11月销售金额
month12  number(10,2)     --12月销售金额

结构转化的SQL语句为:
create or replace view
v_sale(year,month1,month2,month3,month4,month5,month6,month7,month8,month9,month10,month11,month12)
as
    select
    substrb(month,1,4),
    sum(decode(substrb(month,5,2),'01',sell,0)),
    sum(decode(substrb(month,5,2),'02',sell,0)),
    sum(decode(substrb(month,5,2),'03',sell,0)),
    sum(decode(substrb(month,5,2),'04',sell,0)),
    sum(decode(substrb(month,5,2),'05',sell,0)),
    sum(decode(substrb(month,5,2),'06',sell,0)),
    sum(decode(substrb(month,5,2),'07',sell,0)),
    sum(decode(substrb(month,5,2),'08',sell,0)),
    sum(decode(substrb(month,5,2),'09',sell,0)),
    sum(decode(substrb(month,5,2),'10',sell,0)),
    sum(decode(substrb(month,5,2),'11',sell,0)),
    sum(decode(substrb(month,5,2),'12',sell,0))
    from sale
    group by substrb(month,1,4);

体会:要用decode /group by/ order by/sign/sum来实现不同报表的生成
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
CASE应用

1        1        部门a        800        男
2        2        部门b        900        女
3        3        部门a        400        男
4        4        部门d        1400        女
5        5        部门e        1200        男
6        6        部门f        500        男
7        7        部门a        300        女
8        8        部门d        1000        男
9        9        部门d        1230        女
10        10        部门b        2000        女
11        11        部门c        2000        男
12        12        部门b        1200        男

  SELECT jcxm as 部门,COUNT(seq) as 人数,
    SUM(CASE SEX WHEN 1 THEN 1 ELSE 0 END) as 男,
          SUM(CASE SEX WHEN 2 THEN 1 ELSE 0 END) as 女,
    SUM(CASE SIGN(zhi-800) WHEN -1 THEN 1 ELSE 0 END) as 小于800元,
    SUM((CASE SIGN(zhi-800)*SIGN(zhi-1000)                    /*用*来实现<和>功能*/
         WHEN -1 THEN 1 ELSE 0 END)+(CASE zhi
         WHEN 800  THEN 1 ELSE 0 END)) as 从800至999,         /*注意别名不能以数字开头*/
    SUM((CASE SIGN(zhi-1000)*SIGN(zhi-1200)
         WHEN -1 THEN 1 ELSE 0 END)+(CASE zhi
         WHEN 1000 THEN 1 ELSE 0 END)) as 从1000元至1199元,
    SUM((CASE SIGN(zhi-1200) WHEN 1 THEN 1 ELSE 0 END)
    +(CASE zhi WHEN 1200 THEN 1 ELSE 0 END)) as 大于1200元
FroM ttt
GROUP BY jcxm

部门名 人数    男       女   小于800元 从800至999 从1000元至1199元   大于1200元
部门a        3        2        1        2        1           0                              0
部门b        3        1        2        0        1           0                              2
部门c        1        1        0        0        0           0                             1
部门d        3        1        2        0        0           1                             2
部门e        1        1        0        0        0             0                             1
部门f        1        1        0        1        0           0                             0

[/code]

写一些复杂的SQL,大家可以参考
[url][/url],F4950_P8_CRITERIA:766825833740,
有点难度,收藏先!
好东西
看看这个

[code]select substr('fanglf',length('fanglf')-rownum+1,1) as rev
from user_objects  
where rownum <= length('fanglf') order by rownum desc
--
f
a
n
g
l
f
[/code]

呵呵!也算行列转换吧

另外可以定义一个数组类型(或表类型),然后赋值一个串,然后我们可以把数组元素以行的方式显示,并可以转换成表

比如
[code]
create or replace type TP_DM_TableType
as table of number;

    v_ParaType   TP_DM_TableType :=  
                           TP_DM_TableType( 4  , 5   , 6  , 7  , 101, 102,
                                                      110, 201 , 202, 203, 204, 301,
                                                      302, 303 , 304, 305, 306, 307);   


SELECT column_value val
  FROM TABLE ( cast (v_ParaType as  TP_DM_TableType) )

column_value
------------------
4
5
6
7
101
102
110
201
202
203
204
301
302
303
304
305
306
307

[/code]
FLY,你的帖子我不会举一反三

我想把我的一个表行列转化

[code]
要转的表是MR_REPORT
名称        方案        数据类型        大小        是否为空           字段说明
ID        无        VARCHAR2        16        ν        用户编号
AGE        无        VARCHAR2        16        ν        年龄
NAME        无        VARCHAR2        16        ν        姓名
GENDER        无        VARCHAR2        16        ν        性别
COMPANY        无        VARCHAR2        64        ν        用户工作单位
XUELI        无        VARCHAR2        16        ν        学历
INCOME        无        VARCHAR2        16        ν        家庭月收入

我想转成
NO          VARCHAR2        16        
ITEM       VARCHAR2        16
编辑器中这么显示
NO    ITEM
1       ID
2       AGE
3       NAME
4       GENDER
5       COMPANY
6       XUELI
7       INCOME
[/code]
不过我还很纳闷那MR_REPORT的记录还可以对回来吗?!

[ Last edited by xzh2000 on 2004-6-25 at 06:54 PM ]
[code]
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning option
JServer Release 9.2.0.4.0 - Production

SQL> exec print_sql('select * from all_users');
USERNAME                      : SYS
USER_ID                       : 0
CREATED                       : 06-apr-2004 16:11:56
-----------------
USERNAME                      : SYSTEM
USER_ID                       : 5
CREATED                       : 06-apr-2004 16:11:56
-----------------
USERNAME                      : OUTLN
USER_ID                       : 11
CREATED                       : 06-apr-2004 16:11:59
-----------------
USERNAME                      : DBSNMP
USER_ID                       : 19
CREATED                       : 06-apr-2004 16:16:13
-----------------
USERNAME                      : CYBERCAFE
USER_ID                       : 27
CREATED                       : 09-apr-2004 02:01:52
-----------------
USERNAME                      : WMSYS
USER_ID                       : 21
CREATED                       : 06-apr-2004 16:28:43
-----------------
USERNAME                      : CTXSYS
USER_ID                       : 23
CREATED                       : 06-apr-2004 16:28:57
-----------------
USERNAME                      : CARDSALE
USER_ID                       : 26
CREATED                       : 07-apr-2004 09:53:13
-----------------
USERNAME                      : PPC
USER_ID                       : 31
CREATED                       : 19-apr-2004 17:20:25
-----------------
USERNAME                      : PERFSTAT
USER_ID                       : 34
CREATED                       : 29-apr-2004 10:08:25
-----------------

PL/SQL procedure successfully completed.

[/code]
[code]
create or replace
procedure print_table
( p_query in varchar2,
  p_date_fmt in varchar2 default 'dd-mon-yyyy hh24:mi:ss' )
                                                                                 
                                          
-- this utility is designed to be installed ONCE in a database and used
-- by all.  Also, it is nice to have roles enabled so that queries by
-- DBA's that use a role to gain access to the DBA_* views still work
-- that is the purpose of AUTHID CURRENT_USER
AUTHID CURRENT_USER
is
    l_theCursor     integer default dbms_sql.open_cursor;
    l_columnValue   varchar2(4000);
    l_status        integer;
    l_descTbl       dbms_sql.desc_tab;
    l_colCnt        number;
    l_cs            varchar2(255);
    l_date_fmt      varchar2(255);
                                                                                 
    -- small inline procedure to restore the sessions state
    -- we may have modified the cursor sharing and nls date format
    -- session variables, this just restores them
    procedure restore
    is
    begin
       if ( upper(l_cs) not in ( 'FORCE','SIMILAR' ))
       then
           execute immediate
           'alter session set cursor_sharing=exact';
       end if;
       if ( p_date_fmt is not null )
       then
           execute immediate
               'alter session set nls_date_format=''' || l_date_fmt || '''';
       end if;
       dbms_sql.close_cursor(l_theCursor);
    end restore;
begin
                -- dbms_output.enable(100000);
    -- I like to see the dates print out with times, by default, the
    -- format mask I use includes that.  In order to be "friendly"
    -- we save the date current sessions date format and then use
    -- the one with the date and time.  Passing in NULL will cause
    -- this routine just to use the current date format
    if ( p_date_fmt is not null )
    then
       select sys_context( 'userenv', 'nls_date_format' )
         into l_date_fmt
         from dual;
                                                                                 
                                          
       execute immediate
       'alter session set nls_date_format=''' || p_date_fmt || '''';
    end if;
                                                                                 
                                          
    -- to be bind variable friendly on this ad-hoc queries, we
    -- look to see if cursor sharing is already set to FORCE or
    -- similar, if not, set it so when we parse -- literals
    -- are replaced with binds
    if ( dbms_utility.get_parameter_value
         ( 'cursor_sharing', l_status, l_cs ) = 1 )
    then
        if ( upper(l_cs) not in ('FORCE','SIMILAR'))
        then
            execute immediate
           'alter session set cursor_sharing=force';
        end if;
    end if;
                                                                                 
                                          
    -- parse and describe the query sent to us.  we need
    -- to know the number of columns and their names.
    dbms_sql.parse(  l_theCursor,  p_query, dbms_sql.native );
    dbms_sql.describe_columns
    ( l_theCursor, l_colCnt, l_descTbl );
                                                                                 
                                          
    -- define all columns to be cast to varchar2's, we
    -- are just printing them out
    for i in 1 .. l_colCnt loop
        if ( l_descTbl(i).col_type not in ( 113 ) )
        then
            dbms_sql.define_column
            (l_theCursor, i, l_columnValue, 4000);
        end if;
    end loop;
                                                                                 
                                          
    -- execute the query, so we can fetch
    l_status := dbms_sql.execute(l_theCursor);
                                                                                 
                                          
    -- loop and print out each column on a separate line
    -- bear in mind that dbms_output only prints 255 characters/line
    -- so we'll only see the first 200 characters by my design...
    while ( dbms_sql.fetch_rows(l_theCursor) > 0 )
    loop
        for i in 1 .. l_colCnt loop
            if ( l_descTbl(i).col_type not in ( 113 ) )
            then
                dbms_sql.column_value
                ( l_theCursor, i, l_columnValue );
                dbms_output.put_line
                ( rpad( l_descTbl(i).col_name, 30 )
                || ': ' ||
                substr( l_columnValue, 1, 200 ) );
            end if;
        end loop;
        dbms_output.put_line( '-----------------' );
    end loop;
                                                                                 
                                          
    -- now, restore the session state, no matter what
    restore;
exception
    when others then
        restore;
        raise;
end;
[/code]
斑竹,我现在就有一个,但看了你的文章之后还是不太明白,帮帮我行吗?

类似有一个表:

1        1        部门a        800        男    张三
2        2        部门b        900        女    李四
3        3        部门a        400        男    王五
4        4        部门c        1400        女  刘六
5        5        部门a        1200        男  高一
6        6        部门b       500        男    林二

想转换成为

部门a       张三,王五,高一
部门b       李四,林二
部门c       刘六


应该怎样写啊?想了好久都没想到。
给个参考:
如果你能确认jcxm的值
那么可以用下面的方法

数据分别如下:
seq   jcxm       zhi
-------      --------          --------
11     1    0.50
11     2    0.21
11     3    0.25
12     1    0.24
12     2    0.30
12     3    0.22                             

select seq 序号 ,
       sum(decode(jcxm,1, zhi)) 检测项目1||','
       sum(decode(jcxm,2, zhi)) 检测项目2||','
       sum(decode(jcxm,3, zhi)) 检测项目3  检测项目
from ttt
group by seq;

序号      检测项目
---------   ---------------------------
11     0.50,0.21,0.25
12     0.24,0.30,0.22
一个insert的行列转换

[code]
SQL> create table pivoting_test (id int,sales1 number,sales2 number,sales3 number,sales4 number);

Table created.

SQL> insert into pivoting_test values (1,10,20,30,40);

1 row created.

SQL> insert into pivoting_test values (2,100,200,300,400);

1 row created.

SQL> commit;

Commit complete.

SQL> select * from pivoting_test;
        id      sales1      sales2    sales3      sales4
        -----   ------      ------    ------      ------
         1         10         20         30         40
         2        100        200        300        400

SQL> create table all_sales (id int,text varchar2(10),sale number);

Table created.

SQL>   1  insert all                                               
  2  into all_sales values(id,'sales1',sales1)               
  3  into all_sales values(id,'sales2',sales2)               
  4  into all_sales values(id,'sales3',sales3)               
  5  into all_sales values(id,'sales4',sales4)               
  6* select id,sales1,sales1,sales3,sales4 from pivoting_test

SQL> SQL> SQL> SQL> SQL> SQL> SQL> /
into all_sales values(id,'sales2',sales2)
                                   *
ERROR at line 3:
ORA-00904: "SALES2": invalid identifier


SQL> 6 select id,sales1,sales2,sales3,sales4 from pivoting_test

SQL> l
  1   insert all
  2   into all_sales values(id,'sales1',sales1)
  3   into all_sales values(id,'sales2',sales2)
  4   into all_sales values(id,'sales3',sales3)
  5   into all_sales values(id,'sales4',sales4)
  6   select id,sales1,sales2,sales3,sales4
  7   from pivoting_test
SQL> /

8 rows created.

SQL> select * from all_sales order by 1;
         1 sales1             10
         1 sales2             20
         1 sales4             40
         1 sales3             30
         2 sales1            100
         2 sales2            200
         2 sales4            400
         2 sales3            300

8 rows selected.
[/code]
都是高手啊.
再举一例
SQL> select * from test;

B A
- ----------
A a
A aa
A aaa
B b
B bb
B bbb
我要实现
A a,aa,aaa
B b,bb,bbb

SQL> SELECT T1.RN,T2.RN,T3.RN,T1.B,T2.B,T3.B,T1.A,T2.A,T3.A FROM (SELECT ROW_NUMBER() OVER (partition BY B ORDER BY A) RN ,TEST.* FROM TEST) T1,(SELECT ROW_NUMBER() OVER (partition BY B ORDER BY A) RN ,TEST.* FROM TEST) T2,(SELECT ROW_NUMBER() OVER (partition BY B ORDER BY A) RN ,TEST.* FROM TEST) T3
WHERE T1.B = T2.B
  AND T2.B = T3.B;
  2    3  
        RN         RN         RN B B B A          A          A
---------- ---------- ---------- - - - ---------- ---------- ----------
         1          1          1 A A A a          a          a
         2          1          1 A A A aa         a          a
         3          1          1 A A A aaa        a          a
         1          2          1 A A A a          aa         a
         2          2          1 A A A aa         aa         a
         3          2          1 A A A aaa        aa         a
         1          3          1 A A A a          aaa        a
         2          3          1 A A A aa         aaa        a
         3          3          1 A A A aaa        aaa        a
         1          1          2 A A A a          a          aa
         2          1          2 A A A aa         a          aa
         3          1          2 A A A aaa        a          aa
         1          2          2 A A A a          aa         aa
         2          2          2 A A A aa         aa         aa
         3          2          2 A A A aaa        aa         aa
         1          3          2 A A A a          aaa        aa
         2          3          2 A A A aa         aaa        aa
         3          3          2 A A A aaa        aaa        aa
         1          1          3 A A A a          a          aaa
         2          1          3 A A A aa         a          aaa
         3          1          3 A A A aaa        a          aaa
         1          2          3 A A A a          aa         aaa  --这行是我要的数据
         2          2          3 A A A aa         aa         aaa
         3          2          3 A A A aaa        aa         aaa
         1          3          3 A A A a          aaa        aaa
         2          3          3 A A A aa         aaa        aaa
         3          3          3 A A A aaa        aaa        aaa
         1          1          1 B B B b          b          b
         2          1          1 B B B bb         b          b
         3          1          1 B B B bbb        b          b
         1          2          1 B B B b          bb         b
         2          2          1 B B B bb         bb         b
         3          2          1 B B B bbb        bb         b
         1          3          1 B B B b          bbb        b
         2          3          1 B B B bb         bbb        b
         3          3          1 B B B bbb        bbb        b
         1          1          2 B B B b          b          bb
         2          1          2 B B B bb         b          bb
         3          1          2 B B B bbb        b          bb
         1          2          2 B B B b          bb         bb
         2          2          2 B B B bb         bb         bb
         3          2          2 B B B bbb        bb         bb
         1          3          2 B B B b          bbb        bb
         2          3          2 B B B bb         bbb        bb
         3          3          2 B B B bbb        bbb        bb
         1          1          3 B B B b          b          bbb
         2          1          3 B B B bb         b          bbb
         3          1          3 B B B bbb        b          bbb
         1          2          3 B B B b          bb         bbb   ----这行是我要的数据
         2          2          3 B B B bb         bb         bbb
         3          2          3 B B B bbb        bb         bbb
         1          3          3 B B B b          bbb        bbb
         2          3          3 B B B bb         bbb        bbb
         3          3          3 B B B bbb        bbb        bbb

54 rows selected.

所以我们就可以用下面的语句来完成
SQL> SQL> SELECT T1.B,T1.A||','||T2.A||','||T3.A FROM (SELECT ROW_NUMBER() OVER (partition BY B ORDER BY A) RN ,TEST.* FROM TEST) T1,(SELECT ROW_NUMBER() OVER (partition BY B ORDER BY A) RN ,TEST.* FROM TEST) T2,(SELECT ROW_NUMBER() OVER (partition BY B ORDER BY A) RN ,TEST.* FROM TEST) T3
WHERE T1.B = T2.B
  AND T2.B = T3.B
  AND T1.RN = 1
  AND T2.RN = 2
  AND T3.RN = 3;
  2    3    4    5    6  
B T1.A||','||T2.A||','||T3.A
- --------------------------------
A a,aa,aaa
B b,bb,bbb
你好厉害呀!!


夢裡尋它千百度,漠然查找,就在版主貼子中

在此多謝了
[quote]Originally posted by [i]fly115[/i] at 2004-8-18 15:41:
再举一例
SQL> select * from test;

B A
- ----------
A a
A aa
A aaa
B b
B bb
B bbb
我要实现
A a,aa,aaa
B b,bb,bbb

SQL> SELECT T1.RN,T2.RN,T3.RN,T1.B,T2.B,T3.B,T1.A,T2.A,T3.A FR ... [/quote]
你确实是高手,但如果记录数不确定应如何做?
那如果jcxm的数据很多(1000个↑)怎么办?  也用decode一个一个转换??
[quote]Originally posted by [i]marktao1981[/i] at 2004-9-7 14:51:
那如果jcxm的数据很多(1000个↑)怎么办?  也用decode一个一个转换?? [/quote]

如果有这么多转换的意义何在啊
經典經典,Study ing........
[quote]Originally posted by [i]marktao1981[/i] at 2004-9-7 02:51 PM:
那如果jcxm的数据很多(1000个↑)怎么办?  也用decode一个一个转换?? [/quote]
不要老想着用SQL语句来解决问题,首先要分析你的应用,然后去合理去设计数据库。想你提出的问题,应该是数据仓库才会用到的
真是够看的了。有点难懂,先收藏。


我是个刚学ORACLE的菜鸟哦,我都看了一遍也都抄下来了,呵呵
不过我从一开始就不太明白两个问题
就拿你举的行转列的第一个例子说吧,因为我现在的水平也就能看懂第一个,呵呵
第一、decode(jcxm,1, zhi)  这里的值是检查项目1对应的所有值么?比如说0.50和0.24,这个函数可以把检查项目1中的值搜索出来么?
就算能还有第二个问题:
在decode函数把所有1的对应项都搜索出来作为返回值由SUM进行计算,关键在于decode 函数把搜索出来的结果放在哪里?
decode (表达式/字段,比较值1,返回值1
                                比较值2,返回值2
                                           .
                                           .
                                           .
                               比较值n, 返回值n
                                返回值(当一切条件都不符合的返回值)
)
这个是我知道的DECODE函数的模板,就算是公式吧,呵呵。
不知道我记没记错?
如果我没记错的话,我就有点迷惑了,那个SUM函数是什么意思?
他执行了什么样的功能?
我只记得SUM函数是计算总数的,并不知道他还有别的什么功能?~
希望前辈们给我指点指点,谢谢大家了
请大家快点回答我的问题好么?~
我很急的
谢谢,谢谢,谢谢了
[quote]Originally posted by [i]wnj[/i] at 2004-9-27 08:56 PM:
我是个刚学ORACLE的菜鸟哦,我都看了一遍也都抄下来了,呵呵
不过我从一开始就不太明白两个问题
就拿你举的行转列的第一个例子说吧,因为我现在的水平也就能看懂第一个,呵呵
第一、decode(jcxm,1, zhi)  这里 ... [/quote]


表ttt有三个字段
seq  --序列
jcxm --检查项目
zhi  --值

数据分别如下:
seq   jcxm       zhi
-------      --------          --------
11     1    0.50
11     2    0.21
11     3    0.25
12     1    0.24
12     2    0.30
12     3    0.22                             

实现功能
创建视图时移动行值为列值


create view v_view1
as
select seq,
       sum(decode(jcxm,1, zhi)) 检测项目1,
       sum(decode(jcxm,2, zhi)) 检测项目2,
       sum(decode(jcxm,3, zhi)) 检测项目3
from ttt
group by seq;

序号 检测项目1  检测项目2  检测项目3
11     0.50    0.21     0.25
12     0.24    0.30     0.22

首先回答一下为什么要用decode,因为行列转换通常是在原有表的字段基础上,判断满足不同条件的数据放入不同的列,上面的语句的意思可以这么理解
select
(seq )序列,
'如果检查项目列(jcxm)=1,那么取出满足该条件的所有值(zhi)列的合计(sum)并将该字段为命名为(检测项目1)',
'如果检查项目列(jcxm)=2,那么取出满足该条件的所有值(zhi)列的合计(sum)并将该字段为命名为(检测项目2)',
'如果检查项目列(jcxm)=3,那么取出满足该条件的所有值(zhi)列的合计(sum)并将该字段为命名为(检测项目3)'
from ttt
group by 对(seq )序列进行分组;
我看到了,我明白一些了,谢谢你哈!~
现在还有点不明白的就是SUM函数这个合计功能是怎么样实现的?
当DECODE函数找出了对应的所有项之后,SUM函数上通过什么办法把查询到的
所有项合计的呢?~

谢谢你,呵呵,真是麻烦你了。
good!save.


收藏!
:)
@
还在学习中~~~~~~~~~~~~~~
好,收藏!
是不是只能有数值型的字段才行啊?如果都是字符串怎么办
行转换成列
[b]
SQL> create table line_column (id number,s varchar2(10),p int,t date);

表已创建。

SQL> insert into line_column values (1,'$1',10001,sysdate);

已创建 1 行。

SQL> insert into line_column values (2,'$2',10002,sysdate+1);

已创建 1 行。

SQL> insert into line_column values (3,'$3',10003,sysdate+2);

已创建 1 行。

SQL> insert into line_column values (4,'$4',10004,sysdate+3);

已创建 1 行。

SQL> insert into line_column values (5,'$5',10005,sysdate+4);

已创建 1 行。

SQL> commit;

提交完成。

SQL> select * from line_column;

        ID S                   P T
---------- ---------- ---------- ----------
         1 $1              10001 20-6月 -05
         2 $2              10002 21-6月 -05
         3 $3              10003 22-6月 -05
         4 $4              10004 23-6月 -05
         5 $5              10005 24-6月 -05
         
         
SQL> select to_char(t1.id),to_char(t2.id),to_char(t3.id),to_char(t4.id),to_char(t5.id)
  2    from (select id
  3            from line_column
  4           where id = 1) t1,
  5         (select id
  6            from line_column
  7           where id = 2) t2,
  8         (select id
  9            from line_column
10           where id = 3) t3,
11         (select id
12            from line_column
13           where id = 4) t4,
14         (select id
15            from line_column
16           where id = 5) t5
17  union
18  select t1.s,t2.s,t3.s,t4.s,t5.s
19    from (select s
20            from line_column
21           where id = 1) t1,
22         (select s
23            from line_column
24           where id = 2) t2,
25         (select s
26            from line_column
27           where id = 3) t3,
28         (select s
29            from line_column
30           where id = 4) t4,
31         (select s
32            from line_column
33           where id = 5) t5
34  union
35  select to_char(t1.p),to_char(t2.p),to_char(t3.p),to_char(t4.p),to_char(t5.p)
36    from (select p
37            from line_column
38           where id = 1) t1,
39         (select p
40            from line_column
41           where id = 2) t2,
42         (select p
43            from line_column
44           where id = 3) t3,
45         (select p
46            from line_column
47           where id = 4) t4,
48         (select p
49            from line_column
50           where id = 5) t5
51  union
52  select to_char(t1.t),to_char(t2.t),to_char(t3.t),to_char(t4.t),to_char(t5.t)
53    from (select t
54            from line_column
55           where id = 1) t1,
56         (select t
57            from line_column
58           where id = 2) t2,
59         (select t
60            from line_column
61           where id = 3) t3,
62         (select t
63            from line_column
64           where id = 4) t4,
65         (select t
66            from line_column
67           where id = 5) t5;

TO_CHAR(T1.ID)    TO_CHAR(T2.ID)  TO_CHAR(T3.ID)  TO_CHAR(T4.ID)  TO_CHAR(T5.ID)
--------------- ----------------- --------------- --------------- --------------
$1                $2              $3              $4              $5
1                 2               3               4               5
10001             10002           10003           10004           10005
20-6月 -05        21-6月 -05      22-6月 -05      23-6月 -05      24-6月 -05[/b]
阅读(1469) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~