2010-08-09 10 views
2

J'ai données commerequête optimisée pour obtenir min/max

employé:

id Name 
-------- 
1 xyz 
2 abc 
3 qaz 

Employee_A: (Eid - Table des employés, le titre - Table titre)

eid active type title 
------------------------------ 
1  1   1  1 
1  1   2  2 
1  1   4  3 
2  0   3  4 
2  1   2  2 
2  0   6  5 
3  0   1  1 
3  0   6  5 
3  0   4  3 

Titre:

id rank title_name 
-------------------- 
1 1  Manager 
2 1  Asst Manager 
3 2  Staff1 
4 3  Staff2 
5 4  Staff3 

Ma requête ressemble à

SELECT name, t.title_name 
FROM Employee e 
INNER JOIN Employee_A a ON e.id = a.eid 
INNER JOIN title t on a.title = t.id 
WHERE a.type in (1,2) and active = 1 
and t.rank = /* step 1 */ 
(select min(rank) FROM Employee_A a1 INNER JOIN title t1 ON a1.title = t1.id 
WHERE a1.type in (1,2) and active = 1 AND a1.eid = e.id) 
AND a.type = /* step 2 */ 
    (select min(type) FROM Employee_A a2 INNER JOIN title t2 on a2.title = t2.id 
     WHERE a2.type in (1,2) and active = 1 and a2.eid = e.id 
    and t2.rank = 
     (select min(rank) FROM Employee_A a3 INNER JOIN title t3 ON a3.title = t3.id 
      WHERE a3.type in (1,2) and active = 1 AND a3.eid = e.id) 
    ) 

J'ai plus de 400K dossiers et je suis en train d'interroger le type minimum avec rang minimum (2 titres ont même rang si besoin pour sélectionner le titre minimum entre eux). Ma requête prend plus de temps et je veux l'optimiser, y at-il un moyen d'éviter les étapes 1 et 2 et de le faire plus simplement et plus rapidement?

Sortie:

Name title_name 
----------------- 
xyz Manager 
abc Asst Manager 
+1

Peut-être ajouter votre sortie désirée trop s'il vous plaît – gbn

+0

Pouvez-vous poster votre plan d'exécution? –

+0

désolé je ne peux pas, je n'ai pas la permission sur l'un des schémas utilisés dans la requête réelle. –

Répondre

3

Est-ce que faire ce dont vous avez besoin?

;WITH cte AS 
(
SELECT name, t.title_name, 
    row_number() over (partition by e.id order by rank, type) rn 
FROM Employee e 
INNER JOIN Employee_A a ON e.id = a.eid 
INNER JOIN title t on a.title = t.id 
WHERE a.type in (1,2) and active = 1 
) 

select name, title_name from cte 
where rn=1 

Ou une autre alternative

SELECT e.name, t.title_name 
FROM Employee e 
CROSS APPLY 
(
SELECT TOP (1) title_name 
FROM Employee_A a 
INNER JOIN title t on a.title = t.id 
WHERE a.type in (1,2) and active = 1 AND e.id = a.eid 
order by rank, type 
) t 
+0

merci première requête m'a aidé à concevoir ma requête –

3

je être simplifie à l'extrême, mais donner un coup de feu ce:

select emp.name, MIN(a.title), MIN(t.rank) 
from Employee emp 
join Employee_A a on emp.id = a.eid 
        AND a.type in(1,2) 
        and a.active = 1 
join title t on a.title = t.id 
where not exists (select 1 from Employee_A where eid = emp.id and title < a.title and active = 1) 
group by emp.name 
+0

j'ai mis à jour ma question j'ai oublié d'ajouter le nom de titre –

Questions connexes