2010-05-07 7 views
3

Quelqu'un peut m'éclairer à un moyen de filtrer une sous-requête qui se trouve dans une clause FROM? Je voudrais qu'il ressemble à quelque chose comme ceci:TSQL - TOP X dans FROM Sous-requête?

SELECT * 
FROM TABLE_A 
LEFT JOIN (TOP 8 TABLE_B) ON TABLE_B.id = TABLE_A.id 
+0

Vous devriez changer la réponse acceptée à Remus Rusanu. Raja donne la mauvaise réponse en général. – N8allan

Répondre

1

S'il vous plaît essayez ceci:

SELECT 
column_names 
FROM 
TABLE_A A LEFT JOIN (SELECT TOP 8 column_names FROM TABLE_B) as B 
on A.Id=B.ID 

Considérations:

Ne pas utiliser * car il conduirait à des contraintes de performance.

Si vous êtes préoccupé par tout l'ID seulement ensuite l'ID de Table_B

HTH

2
SELECT * 
FROM TableA 
LEFT JOIN (SELECT TOP 8 * FROM TableB) B 
    ON B.id=TableA.id 
4
SELECT * 
FROM TABLE_A AS a 
LEFT JOIN (SELECT TOP 8 id, field1, field2 
      FROM TABLE_b) AS b 
    ON a.id = b.id 

devrait fonctionner.

+0

Voilà où je suis coincé. S'il y a un moyen de mettre un filtre where sur la sous-requête alors je suis en or. Le problème est que le TOP 8 de cette table ne contient pas l'ID que je filtre dans la requête principale. – EWizard

+0

@EWizard - qu'est-ce qui vous fait penser que vous ne pouvez pas utiliser une clause where sur cette sous-requête/table dérivée? –

+0

Oh, je sais que je peux, certainement. Ce n'est pas un ID statique dont j'ai besoin. C'est comme ceci: La TableA est une table d'employés avec EMPID comme clé. La tableB est une table dépendante, avec la clé étrangère étant EMPID. TableB a quelques EMPID qui ont 15 personnes à charge. Je ne veux que le top 8. Donc, dans votre code ci-dessus, Si je pouvais filtrer 8 dépendants en fonction de la forme d'EMPID correspondant à la requête principale, alors je serais d'or. – EWizard

2

Vous pourriez envisager une approche différente tels que:

SELECT * FROM TABLE_A WHERE TABLE_A.ID IN (SELECT TOP 8 ID FROM TABLE_B) 
0

vous pouvez utiliser un ORDER BY, et même faire le TOP N utiliser une variable:

declare @x table (rowid int) 
declare @y table (rowid int) 
INSERT @x (rowID) SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 
INSERT @y (rowID) SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 
DECLARE @z int 
SET @z=2 

SELECT 
    a.*, b.* 
    FROM @x a 
     LEFT JOIN (SELECT TOP (@z) 
         * 
         FROM @y 
         ORDER BY rowid 
       ) b ON a.rowid=b.rowid 

SORTIE:

rowid  rowid 
----------- ----------- 
1   1 
2   2 
3   NULL 
4   NULL 
5   NULL 
6   NULL 
7   NULL 
8   NULL 

(8 row(s) affected) 

EDIT basé sur OPs commentaires:

Le problème est que le TOP 8 de cette table ne contient pas l'ID que je am filtrage dans la requête principale.

declare @x table (rowid int) 
declare @y table (rowid int) 
INSERT @x (rowID) SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 
INSERT @y (rowID) SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 
DECLARE @z int 
SET @z=2 

SELECT 
    a.*, b.* 
    FROM @x a 
     LEFT JOIN (SELECT 
         *, ROW_NUMBER() OVER(ORDER BY rowid) AS RowNumber 
         FROM @y 
       ) b ON a.rowid=b.rowid 
    WHERE b.RowNumber<[email protected] 

SORTIE:

rowid  rowid  RowNumber 
----------- ----------- -------------------- 
6   6   1 
7   7   2 

(2 row(s) affected) 
17

Si vous devez établir une corrélation entre la sous-requête alors vous devez utiliser APPLY au lieu de JOIN:

SELECT * 
FROM TABLE_A 
CROSS APPLY (
SELECT TOP (8) * 
FROM TABLE_B 
WHERE TABLE_B.id = TABLE_A.id 
ORDER BY ...) AS B; 

Cela vous donnera les 8 premières lignes de B pour chaque ligne dans A. Les autres solutions que je vois affichées vous donneront le JOIN entre A et le global TOP 8 à partir de B

+0

merci pour ce post. Je viens de passer 30 minutes à courir après ma queue parce que j'ai fait un mauvais travail de couper et coller - en supprimant le * off de mon top (1) déclaration ... J'ai finalement abandonné le fantôme et googlé; ce qui m'a conduit à votre poste. Tellement content que c'était ici. – plditallo

Questions connexes