SQL Server 如何提高检索最近日期的T-SQL查询性能?

llycmphe  于 2023-01-16  发布在  其他
关注(0)|答案(4)|浏览(109)

我有一个包含以下列的employee

employee_id, name, hire_date, termination_date, rehire_date, is_active

在SQL Server中。我希望检索每个员工的最近雇用、终止雇用或重新雇用日期,但仅限于该员工处于活动状态时。
结果应该包括employee_idname和最近的日期。如何通过一个查询实现这一点?
我可以使用以下方法来完成:

SELECT 
    employee_id, name, MAX(date) as most_recent_date
FROM 
    (SELECT 
         employee_id, name, hire_date AS date 
     FROM 
         employee
     UNION
     SELECT 
         employee_id, name, termination_date 
     FROM 
         employee
     UNION
     SELECT 
         employee_id, name, rehire_date 
     FROM 
         employee) AS t
WHERE 
    employee_id IN (SELECT employee_id 
                    FROM employee 
                    WHERE is_active = 1)
GROUP BY 
    employee_id, name

这个解决方案看起来可行,但我不确定它是否是最有效的方法,我还担心雇员表很大时的性能。
有谁能提出一个更好、更有效的方法吗?

6rqinv9w

6rqinv9w1#

你可以试试这个。

SELECT employee_id, name, (SELECT Max(v) FROM (VALUES (hire_date), (termination_date),(rehire_date)) AS value(v))  as most_recent_date
                    FROM employee 
                    WHERE is_active = 1
knsnq2tg

knsnq2tg2#

逻辑上,这些日期中只有一个不为空,因此它是一个简单的分组依据:

select employee_id, name, 
    max(coalesce(hire_date, termination_date, rehire_date)) as most_recent_date
from Employee
where is_Active = 1
group by employee_id, name;

但是,由于设计似乎已经存在缺陷(为什么不为这些日期设置一个单独的列,为类型设置另一个列),我们无法确定您可以使用的逻辑是否合理:

select employee_id, name max(case 
  when 
  coalesce(hire_date,'00010101') > coalesce(termination_date,'00010101') and 
  coalesce(hire_date,'00010101') > coalesce(rehire_date,'00010101') then hire_date
  when 
  coalesce(termination_date,'00010101') > coalesce(rehire_date,'00010101') then termination_date
  else
  coalesce(rehire_date,'00010101')
  end)
from Employee 
where is_Active = 1
group by employee_id;

或者是其他回复中的一个变体。

tzxcd3kk

tzxcd3kk3#

这是一个有点俗气,但我认为它应该工作。

SELECT        employee_id, name, 
    CASE 
        WHEN MAX(hire_date) > MAX(termination_date) AND 
            MAX(hire_date) > MAX(rehire_date) THEN MAX(hire_date) 
        WHEN MAX(termination_date) > MAX(hire_date) AND 
            MAX(termination_date) > MAX(rehire_date) THEN MAX(termination_date) 
        WHEN MAX(rehire_date) > MAX(hire_date) AND 
            MAX(rehire_date) > MAX(termination_date) THEN MAX(rehire_date) 
    END AS date
FROM            employee
WHERE        (is_active = 1)
GROUP BY employee_id, name
kiayqfof

kiayqfof4#

在SQL数据库和SQL Server 2022中,我们可以使用GREATEST。它将类似于以下内容:

SELECT employee_id, name, GREATEST(hire_date,termination_date,rehire_date ) 
FROM employee
WHERE is_Active = 1

如果你不能够使用这个功能,那么老办法:

SELECT employee_id, name,
       CASE 
            WHEN hire_date > ISNULL(termination_date, '1900-01-01') AND hire_date > ISNULL(rehire_date , '1900-01-01') THEN hire_date
            WHEN termination_date > ISNULL(hire_date, '1900-01-01') AND termination_date > ISNULL(rehire_date , '1900-01-01') THEN termination_date
            WHEN rehire_date > ISNULL(hire_date, '1900-01-01') AND rehire_date > ISNULL(termination_date , '1900-01-01') THEN rehire_date
       END
FROM employee
WHERE is_Active = 1

也许更好看的空句柄。
在这两种情况下,在IO方面应该更好。

相关问题