基于特定列值将SQL列拆分为多个列

时间:2015-06-18 13:18:44

标签: sql hana

我想写一个查询,列出我们在大学提供的课程。一个程序至少包括一个主要的,可能是一个"选项",一个"专业"和一个" subspecialty"。这四个元素中的每一个都有一个代码,它们将它们与主要元素联系起来。

一个专业可以有零个或多个选项,一个选项可以有零个或多个专业,一个专业可以有零个或多个子专业。相反,允许专业没有与之相关的选项。

在结果集中,一行必须包含前一个元素才能拥有下一个元素,即一行不包含major,no选项和专业。与专业相关的专业外观意味着还有一个与该专业相关的选项。

我的问题在于如何存储数据。所有程序数据都在一个表格中,如下所示:

+----------------+---------------+------+
| program_name   | program_level | code |
+----------------+---------------+------+
| Animal Science | Major         |    1 |
| Equine         | Option        |    1 |
| Dairy          | Option        |    1 |
| CLD            | Major         |    2 |
| Thesis         | Option        |    2 |
| Non-Thesis     | Option        |    2 |
| Development    | Specialty     |    2 |
| General        | Subspecialty  |    2 |
| Rural          | Subspecialty  |    2 |
| Education      | Major         |    3 |
+----------------+---------------+------+

所需的输出将如下所示:

+----------------+-------------+----------------+-------------------+------+
| major_name     | option_name | specialty_name | subspecialty_name | code |
+----------------+-------------+----------------+-------------------+------+
| Animal Science | Equine      |                |                   |    1 |
| Animal Science | Dairy       |                |                   |    1 |
| CLD            | Thesis      | Development    | General           |    2 |
| CLD            | Thesis      | Development    | Rural             |    2 |
| CLD            | Non-Thesis  | Development    | General           |    2 |
| CLD            | Non-Thesis  | Development    | Rural             |    2 |
| Education      |             |                |                   |    3 |
+----------------+-------------+----------------+-------------------+------+

到目前为止,我已尝试创建四个加入此"代码"的查询,每个查询都根据不同的" program_level"进行选择。虽然这些字段没有正确组合。

3 个答案:

答案 0 :(得分:0)

使用子查询来构建您想要的内容。

CODE:

SELECT(SELECT m.program_name FROM yourtable m WHERE m.program_level = 'Major' AND y.program_name = m.program_name) AS major_name,
      (SELECT o.program_name FROM yourtable o WHERE o.program_level = 'Option' AND y.program_name = o.program_name) AS Option_name,
      (SELECT s.program_name FROM yourtable s WHERE s.program_level = 'Specialty' AND y.program_name = s.program_name) AS Specialty_name,
      (SELECT ss.program_name FROM yourtable ss WHERE ss.program_level = 'Subspecialty' AND y.program_name = ss.program_name) AS Subspecialty_name, code
FROM yourtable y

输出:

major_name      Option_name Specialty_name  Subspecialty_name   code
Animal Science  (null)      (null)          (null)              1
(null)          Equine      (null)          (null)              1
(null)          Dairy       (null)          (null)              1
CLD             (null)      (null)          (null)              2
(null)          Thesis      (null)          (null)              2
(null)          Non-Thesis  (null)          (null)              2
(null)          (null)      Development     (null)              2
(null)          (null)      (null)          General             2
(null)          (null)      (null)          Rural               2
Education       (null)      (null)          (null)              3

SQL小提琴:http://sqlfiddle.com/#!3/9b75a/2/0

答案 1 :(得分:0)

我找不到比这简单:

/* Replace @Programs with the name of your table */

SELECT majors.program_name, options.program_name, 
    specs.program_name, subspecs.program_name, majors.code
FROM @Programs majors
LEFT JOIN @Programs options 
    ON majors.code = options.code AND options.program_level = 'Option'
LEFT JOIN @Programs specs 
    ON options.code = specs.code AND specs.program_level = 'Specialty'
LEFT JOIN @Programs subspecs 
    ON specs.code = subspecs.code AND subspecs.program_level = 'Subspecialty'
WHERE majors.program_level = 'Major'

编辑:纠正错字"专业",现在应该可以使用。

答案 2 :(得分:0)

这里解决方案的关键是要意识到这里实际存在多个实体存储在同一个表中,并且这些实体需要先被“提取”。

这可以通过在program_level列上过滤的简单子查询来完成。

select ma.major_name, op.option_name, sp.specialty_name,  ss.subspecialty_name, ma.code
from 
   (select code, program_name  as major_name 
    from programs where program_level = 'Major') ma
left outer join
    (select code, program_name as option_name
     from programs where program_level ='Option') op
     on ma.code = op.code    
left outer join
    (select code, program_name as specialty_name
     from programs where program_level ='Specialty') sp
    on op.code = sp.code
left outer join
    (select code, program_name as subspecialty_name
     from programs where program_level ='Subspecialty') ss
    on sp.code = ss.code
order by ma.code asc, 
      ma.major_name asc,
      op.option_name asc,
      sp.specialty_name asc,
      ss.subspecialty_name asc;

这为您提供了所需的输出:

MAJOR_NAME      OPTION_NAME SPECIALTY_NAME  SUBSPECIALTY_NAME   CODE
Animal Science  Dairy       ?               ?                   1   
Animal Science  Equine      ?               ?                   1   
CLD             Non-Thesis  Development     General             2   
CLD             Non-Thesis  Development     Rural               2   
CLD             Thesis      Development     General             2   
CLD             Thesis      Development     Rural               2   
Education       ?           ?               ?                   3   

干杯, 拉斯