多项选择标准

时间:2018-07-02 09:12:07

标签: sql tsql

我有一个表,其中包含:

  • EmployeeID
  • JobTitle
  • 开始日期
  • EndDate

每个EmployeeID的最小记录数为1,在这种情况下,实际上没有最大值-有些人有10、20、30等。

我只需要从此表中选择以下记录:

  1. 如果同事只有1条记录,则总是选择它
  2. 如果同事有多个记录-将它们全部选中,但记录StartDate等于EndDate除外-忽略这些记录
  3. 如果某个同事有多个记录,并且StartDate / EndDate在每个记录中都相同,则仅使用最新的EndDate记录。

通过一些示例可能更容易看到-想象一下这组数据-最后一列(SELECT ??)显示了我想对该记录执行的操作。

+------------+----------+------------+------------+----------+
| EmployeeID | JobTitle | StartDate  |  EndDate   | SELECT?? |
+------------+----------+------------+------------+----------+
|        123 | A        | 01/01/2018 | 01/01/2018 | Y        |
|        456 | A        | 01/01/2018 | 01/01/2018 | N        |
|        456 | B        | 20/01/2018 | 20/02/2018 | Y        |
|        456 | C        | 21/02/2018 | 20/04/2018 | Y        |
|        789 | A        | 15/03/2018 | 15/03/2018 | N        |
|        789 | B        | 15/04/2018 | 15/04/2018 | N        |
|        789 | C        | 15/05/2018 | 15/05/2018 | Y        |
+------------+----------+------------+------------+----------+

我正在尝试尽可能简单地做到这一点,而我却在不使用复杂的CTE的情况下苦苦挣扎

3 个答案:

答案 0 :(得分:2)

我认为可以通过UNION ALL来实现-

SELECT EmployeeID, JobTitle, StartDate, EndDate
FROM Table
GROUP BY EmployeeID, JobTitle
HAVING COUNT(JobTitle) = 1
UNION ALL
SELECT EmployeeID, JobTitle, StartDate, EndDate
FROM Table
WHERE StartDate <> EndDate
GROUP BY EmployeeID, JobTitle
HAVING COUNT(JobTitle) > 1
UNION ALL
SELECT EmployeeID, JobTitle, MAX(StartDate), MAX(EndDate)
FROM Table
WHERE StartDate = EndDate
GROUP BY EmployeeID
HAVING COUNT(JobTitle) > 1

尽管我还没有尝试过,但我认为类似的东西应该可以工作。

答案 1 :(得分:1)

我会做的:

select t.*
from (select t.*,
             sum(case when startdate <> enddate then 1 else 0 end) over (partition by employeeId) as cnt_notequal,
             row_number() over (partition by employeeId order by enddate desc) as seqnum
      from t
     ) t
where (cnt_notequal > 0 and startdate <> enddate) or
      (cnt_notequal = 0 and seqnum = 1);

答案 2 :(得分:0)

我想这将是合适的:

select EmployeeID,
       JobTitle,
       StartDate,
       EndDate
from (select *,test = (case when StartDate = EndDate then
                      lead(EndDate) over (partition by EmployeeID order by EndDate)
                 else null end)
     from @table as t
     ) as t
where test is null

test is here