繁体   English   中英

没有活跃工作的残疾用户的 SQL 查询

[英]SQL Query of disabled users with no active employment

与我们所有的用户和他们的工作有一张桌子。

当某人重新就业时,将为该就业期添加一个新行。 用户名将始终相同。

试图找出最佳方法来查找哪些用户是残疾人且没有活跃的工作。 数据库是 SQL Server 2016。

示例表:

|  username | name      | active | enddate 
+-----------+-----------+--------+----------
| 1111      | Jane Doe  |    1   | 1/3/2022
| 1111      | Jane Doe  |    0   | 1/2/2018
| 1112      | Bob Doe   |    1   | NULL
| 1113      | James Doe |    0   | 1/3/2018
| 1114      | Ray Doe   |    1   | NULL
| 1114      | Ray Doe   |    0   | 2/2/2019
| 1115      | Emma Doe  |    1   | NULL
| 1116      | Sara Doe  |    0   | 3/4/2016
| 1116      | Sara Doe  |    0   | 4/5/2019

理想情况下,即使他们有多个已结束的工作,我也希望每个用户名只获得一行。

因此,查询会为我提供用户为 1113 和 1116 的两行列表。

与这个答案相比,我发现其他答案难以阅读(或没有给出您所要求的内容):

SELECT DISTINCT
    U.username
FROM
    UserEmployment AS U
WHERE
    U.active = 0 AND
    NOT EXISTS (SELECT 'no current active employment' 
                FROM UserEmployment AS C
                WHERE U.username = C.username AND 
                C.active = 1 AND
                (C.enddate IS NULL OR C.enddate >= CONVERT(DATE, GETDATE())))

但这是个人口味。 这将搜索今天没有任何活动记录的所有禁用用户。

只需确保您的enddate列实际上是DATE而不是VARCHAR ,因为它可能会给您带来转换问题。


如果您想显示所有列但每个用户名一次,那么我们将不得不重新加入禁用记录。 我们可以通过使用CROSS APPLYTOP N + ORDER BY来控制行数:

;WITH NonActiveDisabledUsers AS
(
    SELECT DISTINCT
        U.username
    FROM
        UserEmployment AS U
    WHERE
        U.active = 0 AND
        NOT EXISTS (SELECT 'no current active employment' 
                    FROM UserEmployment AS C
                    WHERE U.username = C.username AND 
                    C.active = 1 AND
                    (C.enddate IS NULL OR C.enddate >= CONVERT(DATE, GETDATE())))
)
SELECT
    R.*
FROM
    NonActiveDisabledUsers AS N
    CROSS APPLY (
        SELECT TOP 1        -- Just 1 record
            U.*
        FROM
            UserEmployment AS U
        WHERE
            N.username = U.username AND
            U.active = 0
        ORDER BY
            U.enddate DESC  -- Determine which record should we display
        ) AS R

假设结束日期都在过去,这应该有效:

select username, name
from t
group by username, name
having sum(case when enddate is null then 1 else 0 end) = 0;  -- no NULL values

如果您正在寻找最大结束日期在过去并且没有空结束日期的用户,那么您可以执行以下操作:

select username, name, max(enddate) enddate
from mytable
group by username, name
having 
    max(enddate) < getdate() 
    and max(case when enddate is null then 1 end) is null

你可以这样做

|  username | name      | active | enddate |
--------------------------------------------
| 1111      | Jane Doe  |    1   | 
| 1111      | Jane Doe  |    0   | 1/2/2018
| 1112      | Bob Doe   |    1   |
| 1113      | James Doe |    1   | **30/12/2019**
| 1114      | Ray Doe   |    1   |
| 1114      | Ray Doe   |    0   | 2/2/2019
| 1115      | Emma Doe  |    1   |
| 1116      | Sara Doe  |    0   | 3/4/2016
| 1116      | Sara Doe  |    1   | **30/12/2019**

在这里你可以创建查询

Select * from employee where active=1 and enddate>=getdate()

所以活跃的员工和谁的雇佣结束日期还没有结束

我只能在上面添加的内容是您最好将用户名(名称)放入查找表中,以便它们保留相同的唯一键,但是如果它们的名称更改,它们在数据中保留相同的引用(例如,如果 Sara Doe 得到已婚)。

Select DISTINCT...and ORDER BY enddate DESC

只返回一个结果,并且是最近的。

一种可能性是使最大值处于活动状态。 如果它不是 0,则表示它们处于活动状态。

SELECT 
  username
, name
FROM dbo.YourTable
GROUP BY username
HAVING MAX(CAST(active AS INT)) = 0

以下查询应该适用于您的解决方案:

SELECT UserName
    ,Name
    ,Max(EndDate) AS EndDate
FROM employment
GROUP BY UserName
    ,Name
HAVING username IN (
        SELECT username
        FROM Employment
        WHERE active = 0
            AND enddate IS NOT NULL
            AND username NOT IN (
                SELECT username
                FROM Employment
                WHERE active = 1
                )
        )

结果输出:

1113    James   2018-01-03
1116    Sara    2019-04-05

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM