2009-01-09 8 views
0

J'ai deux tables: TableA et TableB, jointes par TableA.TableA_Id-> 1..n < -TableB.TableA_Id. Un simple PK-FK.Meilleure approche de la requête SQL Server à l'aide de

Je dois extraire distinct Les enregistrements TableA étant donné une certaine condition sur la TableB. Voici ma première approche:

SELECT * FROM TableA A INNER JOIN TableauB B ON A.idA = B.IdA ET B.Date = '2009-01-10' ORDRE PAR A.Id;

C'est sympa, mais ça ne me donne pas d'enregistrements "distincts". Certains enregistrements de la table B peuvent être en double et je pourrais donc obtenir les mêmes enregistrements plus d'une fois.

Je décide donc d'effectuer une sous-sélection (performance n'est pas un problème étant donné que la sous-sélection se terminera probablement avec 20/30 records max):

SELECT * FROM TableA OÙ TableA.Id IN (SELECT DISTINCT IdA FROM TableB WHERE Date = '20090110') COMMANDER PAR TableA.IdA;

Cela fonctionne très bien.

Maintenant la question est: comment puis-je utiliser la jointure interne et toujours obtenir les valeurs distinctes? Est-ce possible en un passage ou la requête imbriquée est un must? Qu'est-ce que je rate?

Répondre

2

utiliser une table dérivée

SELECT * FROM TableA 
JOIN 
(SELECT DISTINCT IdA FROM TableB WHERE Date = '20090110') a 
ON a.IDA = TAbleA.IDA 
ORDER BY TableA.IdA 
1

Et le problème en utilisant

 
SELECT DISTINCT * FROM TableA A INNER JOIN TableB B ON A.idA = B.IdA 
AND B.Date = '2009-01-10' ORDER BY A.Id; 

est?

Si les valeurs IDA en double sont renvoyées, c'est parce que vous sélectionnez trop de colonnes, si vous ne pouvez pas réduire ce que vous sélectionnez, vous avez besoin de la sous-requête.

+0

« Distinct * » est en fait « * », en cas n'y a pas de doublons exacts. –

+0

Exactement, c'est ce que je dis. –

+0

Surtout s'il s'agit de grandes tables, l'approche de la table dérivée où les enregistrements de tableb sont limités avant la jointure peut gagner du temps. C'est une raison de l'essayer. De même, puisque vous ne limitez pas la liste des colonnes à la table, cela ne donnera pas la bonne réponse. – HLGEM

0

Que diriez-vous ceci:

select * from TableA a 
    where a.TableA_Id in 
(select TableA_Id from TableB where [Date] = '2009-01-10') 
order by a.TableA_Id 

Vous pouvez ajouter distinct à la sous-requête si vous voulez, je ne suis pas sûr que cela va améliorer ou réduire preformance désinvolte.

2

Je pense qu'une déclaration existe normale est ce que vous avez besoin:

SELECT * 
FROM TableA A 
WHERE Exists(select B.IdA from TableB B where A.IdA = B.IdA and B.Date = '2009-01-10') 
ORDER BY A.Id; 

Côté performance, il devrait être la meilleure approche.

Si vous avez besoin des valeurs de l'autre table, et d'éviter d'utiliser distincts, vous pourriez vous joindre à une requête sous groupé comme ceci:

Select TableA.*, groupedTableB.OtherData 
From TableA 
Inner join 
(
    select TableB.IdA, Sum(TableB.Data) SummaryData 
    from TableB where TableB.Date = '2009-01-10' 
    group by TableB.IdA 

) groupedTableB on groupedTableB.IdA = TableA.IdA 
+0

Juste pour que vous le sachiez, cette seconde n'est pas une sous-requête, c'est une table dérivée. – HLGEM

+0

Merci pour l'idée. Je vais essayer ça aussi –

Questions connexes