Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL Server-选择具有条件的最新记录_Sql Server_Select_Group By - Fatal编程技术网

Sql server SQL Server-选择具有条件的最新记录

Sql server SQL Server-选择具有条件的最新记录,sql-server,select,group-by,Sql Server,Select,Group By,我有一张这样的桌子 表: ID EnrollDate ExitDate 1 4/1/16 8/30/16 2 1/1/16 null 2 1/1/16 7/3/16 3 2/1/16 8/1/16 3 2/1/16 9/1/16 4 1/1/16 12/12/16 4 1/1/16 12/12/16 4 1/1/16 12/12/16 4 1/1/16 null 5

我有一张这样的桌子

表:

ID  EnrollDate  ExitDate
1   4/1/16      8/30/16 
2   1/1/16      null
2   1/1/16      7/3/16
3   2/1/16      8/1/16
3   2/1/16      9/1/16
4   1/1/16      12/12/16
4   1/1/16      12/12/16
4   1/1/16      12/12/16
4   1/1/16      null
5   5/1/16      11/12/16
5   5/1/16      11/12/16
5   5/1/16      11/12/16
需要选择具有这些条件的最新记录

  • 只有一条记录具有最近的注册日期-选择该记录
  • 两个或多个共享相同的最近注册日期,并且只有一个记录的退出日期或最近退出日期为空-选择具有空的记录。如果没有空记录,则选择最近退出日期的记录
  • 两个或多个具有相同注册和退出日期的记录-如果存在这种情况,请不要选择这些记录
  • 因此,上表的预期结果应为:

    ID  EnrollDate  ExitDate
    1   4/1/16      8/30/16 
    2   1/1/16      null
    3   2/1/16      9/1/16
    4   1/1/16      null
    
    我用groupby编写了查询。我不知道如何选择条件2和3

    select t1.*  from table t1
    INNER JOIN(SELECT Id,MAX(EnrollDate) maxentrydate
    FROM table
    GROUP BY Id)t2 ON EnrollDate = t2.maxentrydate and t1.Id=t2.Id 
    
    请告诉我最好的方法是什么。

    使用
    rank()
    窗口函数,我认为这是可能的

    这是未经测试的,但它应该可以工作:

    select t.ID, t.EnrollDate, t.ExitDate
      from (select t.*,
                   rank() over(
                     partition by ID 
                     order by EnrollDate desc,
                              case when ExitDate is null then 1 else 2 end,
                              ExitDate desc) as rnk
              from tbl t) t
     where t.rnk = 1
     group by t.ID, t.EnrollDate, t.ExitDate
    having count(*) = 1
    
    基本思想是
    rank()
    窗口函数将对值为
    1
    的最“最近”行进行排序,我们在外部查询的
    where
    子句中对其进行筛选


    如果多行具有相同的“最新”数据,则它们都将共享相同的
    1
    ,但会被
    having count(*)=1
    子句过滤掉。

    使用
    行号
    大小写
    表达式来获得所需的结果:

    WITH Cte AS(
        SELECT t.*,
            ROW_NUMBER() OVER(
                PARTITION BY t.ID
                ORDER BY
                    t.EnrollDate DESC,
                    CASE WHEN t.ExitDate IS NULL THEN 0 ELSE 1 END,
                    t.ExitDate DESC
            ) AS rn
        FROM Tbl t
        INNER JOIN (
            SELECT 
                ID, 
                COUNT(DISTINCT CHECKSUM(EnrollDate, ExitDate)) AS DistinctCnt, -- Count distinct combination of EnrollDate and ExitDate per ID
                COUNT(*) AS RowCnt -- Count number of rows per ID
            FROM Tbl
            GROUP BY ID
        ) a
            ON t.ID = a.ID
        WHERE 
            (a.DistinctCnt = 1 AND a.RowCnt = 1)
            OR a.DistinctCnt  > 1
    )
    SELECT 
        ID, EnrollDate, ExitDate
    FROM Cte c 
    WHERE Rn = 1
    
    • 行编号
      中的
      ORDER BY
      子句负责处理条件2和3
    • internaljoin
      WHERE
      子句负责1和4

    左连接用于满足要求。当记录被返回时,我们不想要它

    with B as (
    select id, enrolldate , 
      exitdate,
      row_number() over (partition by id order by enrolldate desc, case when exitdate is null then 0 else 1 end, exitdate desc) rn
     from ab )
     select b1.id, b1.enrolldate, b1.exitdate from b  b1
     left join b b2
     on b1.rn = b2.rn -1 and
        b1.id = b2.id and
        b1.exitdate = b2.exitdate and
        b1.enrolldate = b2.enrolldate
    where b1.rn = 1 and 
         b2.id is nULL