Multiple column subselect in mysql 5 (5.1.42)

Posted by rubber boots on Stack Overflow See other posts from Stack Overflow or by rubber boots
Published on 2010-03-15T20:42:20Z Indexed on 2010/03/15 21:19 UTC
Read the original article Hit count: 194

Filed under:
|
|

This one seems to be a simple problem, but I can't make it work in a single select or nested select. Retrieve the authors and (if any) advisers of a paper (article) into one row.

I order to explain the problem, here are the two data tables (pseudo)

papers (id, title, c_year)
persons (id, firstname, lastname)

plus a link table w/one extra attribute (pseudo):

paper_person_roles(
  paper_id
  person_id
  act_role ENUM ('AUTHOR', 'ADVISER')
)

This is basically a list of written papers (table: papers) and a list of staff and/or students (table: persons)

An article my have (1,N) authors.
An article may have (0,N) advisers.
A person can be in 'AUTHOR' or 'ADVISER' role (but not at the same time).

The application eventually puts out table rows containing the following entries:

TH: || Paper_ID  |  Author(s)          |   Title                 |   Adviser(s)  |
TD: ||   21334   |John Doe, Jeff Tucker|Why the moon looks yellow|Brown, Rayleigh|
...

My first approach was like:
select/extract a full list of articles into the application, eg.

SELECT 
   q.id, q.title
FROM 
   papers AS q
ORDER BY 
   q.c_year
and save the results of the query into an array (in the application). After this step, loop over the array of the returned information and retrieve authors and advisers (if any), via prepared statement (? is the paper's id) from the link table like:
APPLICATION_LOOP(paper_ids in array)
  SELECT 
      p.lastname, p.firstname, r.act_role 
  FROM 
      persons AS p, paper_person_roles AS r
   WHERE 
      p.id=r.person_id AND r.paper_id = ?
   # The application does further processing from here (pseudo):
   foreach record from resulting records
     if  record.act_role eq 'AUTHOR' then join to author_column
     if  record.act_role eq 'ADVISER' then join to avdiser_column
   end
   print id, author_column, title, adviser_column
APPLICATION_LOOP
This works so far and gives the desired output. Would it make sense to put the computation back into the DB?

I'm not very proficient in nontrivial SQL and can't find a solution with a single (combined or nested) select call. I tried sth. like

SELECT
    q.title 
    (CONCAT_WS(' ',
     (SELECT p.firstname, p.lastname AS aunames
      FROM persons AS p, paper_person_roles AS r
      WHERE q.id=r.paper_id AND r.act_role='AUTHOR')
     )
    ) AS aulist
FROM 
    papers AS q, persons AS p, paper_person_roles AS r
in several variations, but no luck ...

Maybe there is some chance?

Thanks in advance

r.b.

© Stack Overflow or respective owner

Related posts about sql

Related posts about mysql