简体   繁体   中英

sql query for selecting data from a table with complex structure

I have a table with below structure.

I am not having control over changing the table.

It has three columns: student_name, student_id, name_id

Now student name could be any number of words. Exactly one word will come in one row. Based on the number of words, name_id will be entered and the student_id will be repeated.

The structure would be some thing like:

say name1 is: Ram Laxman Prasad Sharma

and name2 is: Pandit Gangadhar Vidyadhar Mayadhar Omkarnath Shastri

So the table will look like:

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

I hope I explained the structure clearly.

Now, I want to write a query to read only first four names per student. However, if the number of names is less then four, empty string should go and if its greater then four, first four should go and rest just ignored.

I need to put it in a single select query only, since this query will be passed in a spring batch program. But I am not getting how to loop through nameid column to take first four name id for every student.

How to design this sql for DB2 database v8??

Thanks for reading.

First off, I don't have DB2, so there may be some syntax changes

Try the following

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

I've worked on the assumption that your name_id are chars. Also keep in mind that I had written this query for MySQL and DB2 may have a different syntax

improved version inspired by Amit - if you need all 4 names in 1 column :)

  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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM