Question : Finding multiple matches in join and also having 'grandchild' records in t-SQL

consider these 3 tables:

create table tblFirstTable
(
  FirstTablePK      int not null,
  FirstTableKeyA VARCHAR(2 ) not null,
  FirstTableKeyB VARCHAR(6 ) not null,
  FirstTableAltKeyA VARCHAR(2 ) not null,
  FirstTableAltKeyB VARCHAR(6 ) not null,
  FirstTableAltKeyC VARCHAR(1 ) not null,
  FirstTableAltKeyX VARCHAR(2 ) not null,
  FirstTableAltKeyY VARCHAR(6 ) not null,
  FirstTableAltKeyZ VARCHAR(1 ) not null,
 )

create table tblSecondTable
(
  SecondTablePK            int not null,
  SecondTableKeyA  VARCHAR(2) not null,
  SecondTableKeyB VARCHAR(6) not null,
  SecondTableAltKeyX VARCHAR(2) not null,
  SecondTableAltKeyY VARCHAR(6) not null,
  SecondTableAltKeyZ VARCHAR(1) not null,
  Update_When                      DATETIME not null,
  Update_By                  VARCHAR(50) not null,
)

create table tblThirdTable
(
  ThirdTablePK int not null,
  SecondTableFK      int not null,
  AgentName            VARCHAR(20 ) not null
)

The join between tblFirstTable and tblSecondTable is on
FirstTableKeyA = SecondTableKeyA  AND FirstTableKeyB =SecondTableKeyB

For everyone of these joins, for each corresponding values of {FirstTableAltKeyX,FirstTableAltKeyY,FirstTableAltKeyZ}
there may be 1 or more values in {SecondTableAltKeyX,SecondTableAltKeyY,SecondTableAltKeyZ}. This is the key condition.

I would like to select only records from tblFirsttable when the above key condition is satisfied and also if there are child record for tblSecondTable in tblThirdTable.

Example:
tblFirstTable
1,'AA','BBBBBB','CC','DDDDDD','E','FF','GGGGGG','H'
2,'@@','######','$$','%%%%%%','^','&&','******','('
3,'QQ','WWWWWW','EE','RRRRRR','T','YY','UUUUUU','I'

tblSecondTable
10,'AA','BBBBBB','II','JJJJJJ','K',datetime,John
11,'AA','BBBBBB','LL','MMMMMM','N',datetime,Mary
12,'AA','BBBBBB','OO','PPPPPP','Q',datetime,Joe
13,'@@','######','))','------','=',datetime,Jim
14,'@@','######','~~','!!!!!!',';',datetime,Jack
15,'QQ','WWWWWW','AA','SSSSSS','D'

tblThirdTable
20,11,'Miriam Racques'
21,12,'Roger Portes'
22,15,'Mike Penguert'

*For 'AA','BBBBBB' in tblFirstTable, we have records in tblSecondTable also, 3 of them. So we have multiple matches. This is criteria #1. And at least one of them has a child record in tblThirdTable. Hence both conditions satisfy, and we would like to bring the record in tblFirstTable in the query.

*For '@@','######' in tblFirstTable, we have records in tblSecondTable also, 2 of them.So we have multiple matches. This is criteria #1. But none of them have child records in tblThirdTable; because second criteria fails, we do not have to bring the row from tblFirstTable.

*For 'QQ','WWWWWW' in tblFirstTable, we have only one match in tblSecondTable (no multiple matches). Even though this has a child record (second criteria is satisfied), because the first criteria is not satisfied, we will not bring the row from tblFirstTable in the query.

how would you build the result desired in t-SQL code?.

thank you

Answer : Finding multiple matches in join and also having 'grandchild' records in t-SQL

Well, can be a few strategies as you can see from above...

The underlying relationships are resolved using a base of (if we needed all details) :

select T1.*, T2.*, T3.*
from tblFirstTable T1
inner join tblSecondTable T2 on T1.FirstTableKeyA = T2.SecondTableKeyA AND T1.FirstTableKeyB =T2.SecondTableKeyB
inner join tblThirdTable T3 on T2.SecondTablePK = T3.SecondTableFK

-- Considering there are PK's and FK's we assume appropriate indexing on those.
-- So, reasonable to assume indexing on the TableKeyA and TableKeyB columns in their respective tables as well.
-- Which means that we can be reasonably happy using joins.
-- But we only really need counters... Not details...

select FirstTablePK as FPK, count(secondTablePK) as T2_count, count(thirdTablePK) as T3_count  
from tblFirstTable T1
inner join tblSecondTable T2 on T1.FirstTableKeyA = T2.SecondTableKeyA AND T1.FirstTableKeyB =T2.SecondTableKeyB
inner join tblThirdTable T3 on T2.SecondTablePK = T3.SecondTableFK
group by FirstTablePK
having count(secondTablePK) > 1

-- Note, we dont have to count T3_count really, because the inner join will resolve the existance of at least 1 entry in tblThirdTable
-- and really, we dont have to select T2_count because the Having clause does that count for us
-- But we do need details, so, have to get back the tblFirstTable data.

select *
from (select FirstTablePK as FPK  
      from tblFirstTable T1
      inner join tblSecondTable T2 on T1.FirstTableKeyA = T2.SecondTableKeyA AND T1.FirstTableKeyB =T2.SecondTableKeyB
      inner join tblThirdTable T3 on T2.SecondTablePK = T3.SecondTableFK
      group by FirstTablePK
      having count(secondTablePK) > 1) s
inner join tblFirstTable on FPK = FirstTablePK

-- now, we have a subquery for our counter and select back the tblFirstTable
-- so, really we can split out elements of that subquery so we only refer to tables once if possible
-- and because it is a simple counter, we can actually have that part as the subquery only.

select *
from tblFirstTable T1
Where 1 < (select count(secondTablePK)
           from tblSecondTable T2
           inner join tblThirdTable T3 on T2.SecondTablePK = T3.SecondTableFK
           where T1.FirstTableKeyA = T2.SecondTableKeyA AND T1.FirstTableKeyB =T2.SecondTableKeyB)

-- there might be additional ways to explore, but think that does give the best performance, and the deliberations / steps used to get to that point :)
Random Solutions  
 
programming4us programming4us