views:

15

answers:

2

I have a Master and Detail table, the Detail linking to the Master record on a FK reference.

I need to display all the data from the Master table, and the corresponding number of details for each record, i.e.

MASTER TABLE
ID Name  Age
1  John  15
2  Jane  14 
3  Joe   15

DETAIL
MasterID Subjects
1        Trigonometry
1        Chemistry
1        Physics
1        History
2        Trigonometry
2        Physics

Thus, when I ran the SQL statement, I would have the following result:

ID Name Age #Subjects
1  John 15  4  
2  Jane 14  2
3  Joe  15  0

Thanks!

+3  A: 

This may be useful

SELECT mt.ID, mt.NAME, mt.AGE, COUNT(d.MasterID) as [#Subjects]
FROM MasterTable mt
LEFT OUTER JOIN Detail d on mt.ID = d.ID
GROUP BY mt.ID, mt.NAME, mt.AGE
ORDER BY mt.ID
bobs
You'll need to coalesce d.MasterID to zero before counting it, or it'll return NULL for master records with no children (like Joe).
djacobson
Great. The keyword missing from the SQL I wrote was the word *OUTER*.
Batuta
@djacobson - could you explain further? Right now, it is returning 0 if no detail record was found, as posted by @bobs.
Batuta
Don't need the coalesce when using COUNT(column). You would need it for a SUM, as an example. If you use coalesce in this case, it would return 1 instead of 0.
bobs
@bobs You're right. I was confused, because `COUNT(column)` skips NULLs, but it does indeed return 0 when it encounters them, not NULL. Good call!
djacobson
+2  A: 
select id, 
       name, 
       age, 
       ( select count(*) 
           from detail 
          where master.id = detail.id )  as record_count
  from master

syntax adjusted depending on what db you are using

Ray
+1: Valid, though I'm not a fan of sub-selects
OMG Ponies
I agree about sub-queries in general. But in this case, I don't. I just tried it on some large real tables. Both generated exactly the same query plan. To me, the sub-query version is more explicitly descriptive of what I am trying to do.
Ray