根据特定列值将 SQL 列拆分为多列
Splitting SQL Columns into Multiple Columns Based on Specific Column Value
我想编写一个查询,列出我们在我的大学提供的课程。一个项目至少包括一个专业,可能还有一个 "option"、一个 "specialty" 和一个 "subspecialty"。这四个要素中的每一个都详细说明了将它们与专业相关联的代码。
一个专业可以有零个或多个选项,一个选项可以有零个或多个专业,一个专业可以有零个或多个子专业。相反,一个专业被允许没有与之相关的选项。
在结果集中,一行必须包含前一个元素才能有下一个元素,即一行将不包含专业、选项和专业。与专业相关的专业的出现意味着还有一个与该专业相关的选项。
我的问题在于数据的存储方式。所有程序数据都在一个 table 中,布局如下:
+----------------+---------------+------+
| 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 |
+----------------+-------------+----------------+-------------------+------+
到目前为止,我已尝试创建四个连接此 "code" 的查询,每个查询都基于不同的 "program_level"。但是这些字段没有正确组合。
使用子查询来建立你想要的。
代码:
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 Fiddle: http://sqlfiddle.com/#!3/9b75a/2/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'
编辑:更正了拼写错误 "Speciality",现在应该可以使用了。
此处解决方案的关键是要意识到实际上有多个实体存储在同一个 table 中,并且这些实体需要先 'extracted'。
这可以通过过滤 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
干杯,
拉斯
我想编写一个查询,列出我们在我的大学提供的课程。一个项目至少包括一个专业,可能还有一个 "option"、一个 "specialty" 和一个 "subspecialty"。这四个要素中的每一个都详细说明了将它们与专业相关联的代码。
一个专业可以有零个或多个选项,一个选项可以有零个或多个专业,一个专业可以有零个或多个子专业。相反,一个专业被允许没有与之相关的选项。
在结果集中,一行必须包含前一个元素才能有下一个元素,即一行将不包含专业、选项和专业。与专业相关的专业的出现意味着还有一个与该专业相关的选项。
我的问题在于数据的存储方式。所有程序数据都在一个 table 中,布局如下:
+----------------+---------------+------+
| 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 |
+----------------+-------------+----------------+-------------------+------+
到目前为止,我已尝试创建四个连接此 "code" 的查询,每个查询都基于不同的 "program_level"。但是这些字段没有正确组合。
使用子查询来建立你想要的。
代码:
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 Fiddle: http://sqlfiddle.com/#!3/9b75a/2/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'
编辑:更正了拼写错误 "Speciality",现在应该可以使用了。
此处解决方案的关键是要意识到实际上有多个实体存储在同一个 table 中,并且这些实体需要先 'extracted'。
这可以通过过滤 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
干杯, 拉斯