Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SELECT single row from child table for each row in parent table

Tags:

sql

ms-access

I am trying to get only one row from child table for each parent row with child fields included, I have been trying with GRUOP BY but with no success :( Here is my initial SELECT

SELECT pID, lastname 
 FROM parent 
  LEFT JOIN 
   (SELECT cID, pID, phone, company, title FROM child) as child 
   ON parent.pID = child.pID

Here is the tables strcture

CREATE TABLE parent (
    pID Counter(1,1) PRIMARY KEY,
    firstname VarChar(24) DEFAULT '',
    lastname VarChar(20) DEFAULT ''
);

CREATE TABLE child (
    cID Counter(1,1) PRIMARY KEY,
    pID int DEFAULT '0',
    phone VarChar(16) DEFAULT '',
    company VarChar(24) DEFAULT '',
    title VarChar(24) DEFAULT '',
    address TEXT
);
like image 989
meYnot Avatar asked May 07 '12 08:05

meYnot


2 Answers

"get only one row from child table for each parent row with child fields included"

That sounds like the child table can have more than one row for the same pID value. And you want only one child row for each pID.

SELECT pID, Min(cID) AS MinOfcID
FROM child
GROUP BY pID;

Join that GROUP BY query back to the child table again to retrieve the other columns for each target cID value. Save this query as qryChild.

SELECT
    c.pID,
    c.cID,
    c.phone,
    c.company,
    c.title,
    c.address
FROM
    (
        SELECT pID, Min(cID) AS MinOfcID
        FROM child
        GROUP BY pID
    ) AS map
    INNER JOIN child AS c
    ON c.cID = map.MinOfcID;

Finally, to include lastname values, join the parent table to qryChild.

like image 83
HansUp Avatar answered Sep 27 '22 19:09

HansUp


You didn't state your DBMS so this is a standard ANSI solution:

SELECT pID, lastname 
FROM parent 
  LEFT JOIN (
         SELECT pID, 
                row_number() over (partition by pid order by cid) as rn
         FROM child
         ) as child 
         ON parent.pID = child.pID and child.rn = 1

Which rows you define as the "first" row is up to you. There is no such as a "first" row unless you sort the rows - that's what the part order by cid does in the partition clause. So if you want something different as the "first" row, you need to change that.

Btw: there is no need to select all columns from the child table if you don't use them.

like image 38
a_horse_with_no_name Avatar answered Sep 27 '22 18:09

a_horse_with_no_name