开发者

Optimized query to get min/max

开发者 https://www.devze.com 2023-01-10 15:56 出处:网络
I have data as Employee: idName -------- 1xyz 2abc 3qaz Employee_A: (Eid - employee table, title - title table)

I have data as

Employee:

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

Employee_A: (Eid - employee table, title - title table)

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

Title:

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

My query looks like

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)
    )

I have more than 400K records and I'm trying to query minimum type with minimum rank (2 titles have same rank so need to select minimum title between them). My query is taking more time and I want to optimize it, is there a way i can avoid step 1, 2 and do it more simpler and fast?

Output:

Name   title_name
-----------------
xyz    Manager
abc    Asst Manager


Does this do what you need?

;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

Or another 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


I may be oversimplifying, but give this a shot:

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

精彩评论

暂无评论...
验证码 换一张
取 消