J'ai 2 tables, tableA et tableB
tableA - id int name varchar(50) tableB - id int fkid int name varchar(50)
Les deux tables sont jointes entre id et fkid.
Voici des exemples de lignes de tableA
Ci-dessous est sortie de tableB
Je veux joindre les deux tables et get seulement la rangée supérieure de la table jointe. Donc, la sortie sera comme ci-dessous
Id Name fkid 1 P1 1 2 P2 4 3 P3 null
Voici le violon Sql
Comment puis-je y parvenir avec une seule requête? Je sais que je peux faire une boucle dans mon code .net et récupérer les lignes supérieures. Mais je le veux en une seule requête.
select ta.id, ta.name, min(tb.id) from tableA ta left join tableB tb on tb.fkid=ta.id group by ta.id, ta.name
select a.id,a.name,b.fid from tableA a left join ( select min(id) fid ,fkid from tableB group by fkid )b on a.id = b.fkid
Vous pourriez faire ceci:
;WITH CTE AS ( SELECT ROW_NUMBER() OVER(PARTITION BY fkID ORDER BY ID) AS RowNbr, tableB.* FROM tableB ) SELECT * FROM tableA LEFT JOIN CTE ON CTE.fkID=tableA.id AND CTE.RowNbr=1
Démo ici
Ou sans fonction de window. Comme ça:
SELECT * FROM tableA LEFT JOIN ( SELECT ROW_NUMBER() OVER(PARTITION BY fkID ORDER BY ID) AS RowNbr, tableB.* FROM tableB ) as tbl ON tbl.fkID=tableA.id AND tbl.RowNbr=1
Démo ici
Mettre à jour:
La raison pour laquelle je choisis de le faire avec row_number est que s'il y a plus de colonnes dans la tableB, alors l'exemple. Ensuite, il n'y a pas besoin d'agrégat supplémentaire si vous voulez afficher plus de colonnes. Pour moi personnellement, il est plus clair avec une command par sur l'ID