用于从具有复杂结构的表中选择数据的 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 查询的主要内容,如果未能解决你的问题,请参考以下文章

用于从表中选择具有最新时间戳的行的 JOOQ 代码

用于从连接表中进行选择的 T-SQL 查询,其中有可变数量的参数?

从名称具有相同首字母的表中选择

从具有类别和子类别的表中进行选择的 SQL 查询

如何从具有字典列表的表中查询,仅针对某些键 (BigQuery) SQL

从具有行号的表中选择到 c# 数据表给出错误