SQL行进入列

时间:2013-11-25 09:30:48

标签: sql oracle

请帮我将我的行转换为列而不是重复它们。我一直在寻找和申请方法,但我不能满足我的要求。

create table PROGRAMMER
(
PERSON varchar(15),
LANGUAGE varchar(20),
LEVELS varchar(15)
);

insert into PROGRAMMER (PERSON, LANGUAGE, LEVELS) values ('CARL', 'JAVA', 'SENIOR');
insert into PROGRAMMER (PERSON, LANGUAGE, LEVELS) values ('CARL', 'PHP', 'MID');
insert into PROGRAMMER (PERSON, LANGUAGE, LEVELS) values ('CARL', 'VB.NET', 'JUNIOR');
insert into PROGRAMMER (PERSON, LANGUAGE, LEVELS) values ('GARY', 'C#', 'MID');
insert into PROGRAMMER (PERSON, LANGUAGE, LEVELS) values ('GARY', 'VB.NET', 'MID');
insert into PROGRAMMER (PERSON, LANGUAGE, LEVELS) values ('RALPH', 'PHP', 'SENIOR');
insert into PROGRAMMER (PERSON, LANGUAGE, LEVELS) values ('RALPH', 'RUBY', 'JUNIOR');
insert into PROGRAMMER (PERSON, LANGUAGE, LEVELS) values ('RALPH', 'JAVASCRIPT', 'SENIOR');

我想使用“LEVELS”作为列来表示这样的表,其中一些行具有相同的人,因为它们在不同语言中具有相同的级别。如果没有条目,其他列将为空。

|  PERSON  |  SENIOR  |    MID    |  JUNIOR  |
----------------------------------------------
|  CARL    |   JAVA   |    PHP    |   VB.NET |
|  GARY    |          |    C#     |          |
|  GARY    |          |   VB.NET  |          |
|  RALPH   |   PHP    |           |  RUBY    |
|  RALPH   |JAVASCRIPT|           |          | 

谢谢。

3 个答案:

答案 0 :(得分:3)

使用转置无法实现此目的。而是尝试使用natural full outer join

WITH T
    AS (SELECT
             P.*,
             ROW_NUMBER ( )
                 OVER (PARTITION BY PERSON, LEVELS ORDER BY LANGUAGE)
                 R
        FROM
             PROGRAMMER P)
SELECT
      PERSON,
      SENIOR,
      MID,
      JUNIOR
FROM
      (SELECT
            PERSON,
            R,
            LANGUAGE SENIOR
       FROM
            T
       WHERE
            LEVELS = 'SENIOR')
      NATURAL FULL OUTER JOIN (SELECT
                                PERSON,
                                R,
                                LANGUAGE MID
                          FROM
                                T
                          WHERE
                                LEVELS = 'MID')
      NATURAL FULL OUTER JOIN (SELECT
                                PERSON,
                                R,
                                LANGUAGE JUNIOR
                          FROM
                                T
                          WHERE
                                LEVELS = 'JUNIOR');

你得到了

PERSON          SENIOR               MID                  JUNIOR              
--------------- -------------------- -------------------- --------------------
CARL            JAVA                 PHP                  VB.NET              
GARY                                 C#                                       
GARY                                 VB.NET                                   
RALPH           JAVASCRIPT                                RUBY                
RALPH           PHP                                                           

5 rows selected.

答案 1 :(得分:0)

  1. 您无法在oracle中创建名为“LEVEL”的列,因为它是一个保留关键字。
  2. 您创建表格和插入语句矛盾
  3. 每个人都可以与多种语言相关联,并具有相同的熟练程度。因此无法根据级别进行转置。
  4. 相反,您可以尝试基于语言进行转置。
  5. 如果您有明确的语言列表,则可以使用MAX和DECODE
  6. PIVOT无法使用,因为它需要字符串的聚合函数。!!
  7. 如果您没有明确的列表,那么您可以使用Oracle connect by
  8. 如果您有明确的语言列表,请尝试此操作

    SELECT
          X.PERSON,
          MAX ( DECODE ( X.LANGUAGE, 'JAVA', X.LEVELS ) ) "JAVA",
          MAX ( DECODE ( X.LANGUAGE, 'PHP', X.LEVELS ) ) "PHP",
          MAX ( DECODE ( X.LANGUAGE, 'VB.NET', X.LEVELS ) ) "VB.NET",
                MAX ( DECODE ( X.LANGUAGE, 'C#', X.LEVELS ) ) "C#",
          MAX ( DECODE ( X.LANGUAGE, 'RUBY', X.LEVELS ) ) "RUBY",
          MAX ( DECODE ( X.LANGUAGE, 'JAVASCRIPT', X.LEVELS ) ) "JAVASCRIPT"
    FROM
          (SELECT
                O.PERSON,
                O.LEVELS,
                 O.LANGUAGE 
           FROM
                PROGRAMMER O) X
    GROUP BY
          X.PERSON;
    
    
    PERSON          JAVA            PHP             VB.NET          C#             RUBY            JAVASCRIPT     
    --------------- --------------- --------------- --------------- -------------- --------------- ---------------
    CARL            SENIOR          MID             JUNIOR                         
    GARY                                            MID             MID            
    RALPH                           SENIOR                                         JUNIOR          SENIOR         
    
    3 rows selected.
    

答案 2 :(得分:0)

在设计子查询时遇到了很大的挑战,请按照您的说法在PROGRAMMER表上尝试此查询:

select t1.person,t1.language as SENIOR,t2.language as MID,t3.language as JUNIOR  
from
(select person,language from PROGRAMMER where levels = 'SENIOR' union all
select distinct person,null as language from PROGRAMMER where person not in(select distinct person from PROGRAMMER where levels = 'SENIOR'))t1,
(select person,language from PROGRAMMER where levels = 'MID' union all
select distinct person,null as language from PROGRAMMER where person not in(select distinct person from PROGRAMMER where levels = 'MID'))t2,
(select person,language from PROGRAMMER where levels = 'JUNIOR' union all
select distinct person,null as language from PROGRAMMER where person not in(select distinct person from PROGRAMMER where levels = 'JUNIOR'))t3
where 
t1.person = t2.person and t1.person = t3.person;