2010-04-21 24 views
1

Je souhaite rejoindre une table sous-requête/dérivée contenant une clause WITH (la clause WITH est nécessaire pour filtrer sur ROW_NUMBER() = 1). Dans Teradata, quelque chose de similaire fonctionnerait bien, mais Teradata utilise QUALIFY ROW_NUMBER() = 1 au lieu d'une clause WITH.SQL Server: jointure sur une table dérivée contenant la clause WITH?

Voici ma tentative de cette jointure:

-- want to join row with max StartDate on JobModelID 
INNER JOIN (
    WITH AllRuns AS (
     SELECT *, 
      ROW_NUMBER() OVER (PARTITION BY JobModelID ORDER BY StartDate DESC) AS RowNumber 
     FROM Runs 
    ) 
    SELECT * FROM AllRuns WHERE RowNumber = 1 
) Runs 
ON JobModels.JobModelID = Runs.JobModelID 

Qu'est-ce que je fais mal?

Répondre

0

Ajout d'une condition de jointure est probablement moins efficace, mais fonctionne généralement bien pour moi.

INNER JOIN (
    SELECT *, 
      ROW_NUMBER() OVER 
      (PARTITION BY JobModelID 
      ORDER BY StartDate DESC) AS RowNumber 
     FROM Runs 
    ) Runs 
ON JobModels.JobModelID = Runs.JobModelID 
AND Runs.RowNumber = 1 
+0

Une idée combien moins efficace ce serait? – jnylen

+1

@jnylen, Avez-vous essayé de profiler cette requête? Plans d'exécution, profileur, statistiques client? –

+0

@jnylen: Je suis d'accord avec Astander. Ma règle générale: si la requête revient dans un délai raisonnable, c'est bon. Sinon, je commence à chercher des hotspots et j'essaie de refactoriser. Je n'ai jamais eu à refactor de code comme ce que j'ai montré ci-dessus. – bernie

1

Vous pouvez utiliser plusieurs clauses WITH. Quelque chose comme

;WITH AllRuns AS ( 
     SELECT *, 
       ROW_NUMBER() OVER (PARTITION BY JobModelID ORDER BY StartDate DESC) AS RowNumber 
     FROM Runs 
), 
Runs AS(
     SELECT * 
     FROM AllRuns 
     WHERE RowNumber = 1 
) 

SELECT * 
FROM ... INNER JOIN ( 
     Runs ON JobModels.JobModelID = Runs.JobModelID 

Pour plus de détails sur les usages/structure/règles voir WITH common_table_expression (Transact-SQL)

+0

Laide, mais cela semble fonctionner. Quel est le problème fondamental ici - manque de support pour les clauses WITH dans les tables dérivées? En outre, j'ai été en mesure d'éliminer la deuxième clause WITH en se joignant sur '(SELECT * FROM AllRuns WHERE RowNumber = 1)'. – jnylen

+0

Je ne suis pas d'accord sur le fait que plusieurs conditions dans une clause with sont UGLY. Il est légèrement différent de sintac à plusieurs sous-sélections, ** ce qui dans la plupart des cas le rend extrêmement difficile à lire. ** –

+0

Je veux dire moche dans le sens que le SQL pour faire la tâche de la sous-requête (filtrer la table 'Runs' pour obtenir une ligne par 'JobModelID') est maintenant partagée entre le début de la requête et la sous-requête. – jnylen