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
);
"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
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With