用于从具有复杂结构的表中选择数据的 sql 查询
Posted
技术标签:
【中文标题】用于从具有复杂结构的表中选择数据的 sql 查询【英文标题】:sql query for selecting data from a table with complex structure 【发布时间】:2012-03-17 11:37:12 【问题描述】:我有一个具有以下结构的表。
我无法控制更改表。
它有三列:student_name、student_id、name_id
现在学生姓名可以是任意数量的单词。恰好一个字会排成一排。根据字数输入name_id,重复student_id。
结构类似于:
说 name1 是:Ram Laxman Prasad Sharma
name2 是:Pandit Gangadhar Vidyadhar Mayadhar Omkarnath Shastri
所以表格看起来像:
student_name | student_id | name_id
-------------------------------------------------
Ram 1 1
Laxman 1 2
Prasad 1 3
Sharma 1 4
Pandit 2 1
Gangadhar 2 2
Vidyadhar 2 3
Mayadhar 2 4
Omkarnath 2 5
Shastri 2 6
我希望我能清楚地解释结构。
现在,我想编写一个查询来读取每个学生的前四个姓名。但是,如果名称的数量少于四个,则应该删除空字符串,如果大于四个,则应该删除前四个,然后忽略。
我只需要把它放在一个单一的选择查询中,因为这个查询将在一个 spring 批处理程序中传递。但是我不知道如何遍历 nameid 列来获取每个学生的前四个 name id。
如何为 DB2 数据库 v8 设计这个 sql??
感谢阅读。
【问题讨论】:
oh v8 :(( 在最新版本中您可以使用xmlcast(xmlgroup(...
,但请查看xmlagg()
【参考方案1】:
受 Amit 启发的改进版本 - 如果您需要 1 列中的所有 4 个名称 :)
select
t1.student_name ||
coalesce(' ' || t2.student_name, '') ||
coalesce(' ' || t3.student_name, '') ||
coalesce(' ' || t4.student_name, '') as "first 4 names"
from mytable t1
left join mytable t2 on t1.student_id = t2.student_id and t2.name_id = 2
left join mytable t3 on t1.student_id = t3.student_id and t3.name_id = 3
left join mytable t4 on t1.student_id = t4.student_id and t4.name_id = 4
where t1.name_id = 1
【讨论】:
它可以工作......但是,我需要将它放在前面提到的单独字段中......因为我必须将它们发送到下游的固定格式文件......试图这样做...... 分开列或分开行???我没有在您的问题中找到该要求.. 列很简单,对于行你必须使用with temp (student_name, name_id) as values('', 1), ('', 2), ... select * from mytable cross join temp
- 我希望你自己弄清楚,因为我必须赶火车【参考方案2】:
首先,我没有 DB2,所以可能会有一些语法变化
试试下面的
select t1.student_id, ifnull(t2.names, ' ') from
(select distinct(student_id) as student_id
from tab ) as t1
left outer join
(
select tab1.student_id, ifnull(concat(tab1.student_name, ' ',
tab2.student_name, ' ',
tab3.student_name, ' ',
tab4.student_name),'') as names
from (select * from tab where name_id = '1') tab1
inner join (select * from tab where name_id = '2') tab2
on tab1.student_id = tab2.student_id
inner join (select * from tab where name_id = '3') tab3
on tab1.student_id = tab3.student_id
inner join (select * from tab where name_id = '4') tab4
on tab1.student_id = tab4.student_id
) as t2
on t1.student_id = t2.student_id
我假设您的 name_id 是字符。还要记住,我为 mysql 编写了这个查询,而 DB2 可能有不同的语法
【讨论】:
我想你已经假设这里总是有四个词。如果只有三个字怎么办。最后一次内部连接会发生什么。它不会失败吗? @AmitBhargava 现在它并没有像更复杂那样固定,如果学生有 2 个名字,它仍然返回 ' ' :(( 但我保留 +1 以获得灵感.. 这不起作用.. 第一个原因 - tab4.student_name 中只有三个单词时会出现什么作为 name4 ? @NikunjChauhan 如果学生的姓名少于四个,则返回问题中所述的 ' '。我误解了吗? @AmitBhargava:谢谢! +1 努力!以上是关于用于从具有复杂结构的表中选择数据的 sql 查询的主要内容,如果未能解决你的问题,请参考以下文章
用于从连接表中进行选择的 T-SQL 查询,其中有可变数量的参数?