根据另一个表中的数据,仅获取每个clientid每行非唯一列的前1个

时间:2019-01-15 13:32:39

标签: sql sql-server sql-server-2008

假设我有return Container( height: 120.0, padding: EdgeInsetsDirectional.only(start: 8.0), child: ListView.builder( itemBuilder: _buildListItem(), scrollDirection: Axis.horizontal, itemCount: arrayItems.length, ), );

这包含特定ClientStatusHistory的状态更改历史记录。

该表如下所示:

(日期格式:DD / MM / YYYY)

ClientStatusHistory:

(有一个名为ID的自动递增PK列)

Client

反映当前状态的所有行/记录的DateEnded列均为Null。

我如何将他们的所有状态拉到当前状态之前,并将其插入临时表中?

我本来打算使用ClientID | StatusID | DateStarted | DateEnded 1 | 5 | 01/01/2000 | 01/01/2019 1 | 7 | 01/01/2019 | 11/01/2019 1 | 8 | 11/01/2019 | Null 2 | 5 | 01/01/2000 | 01/01/2019 2 | 7 | 01/01/2019 | 11/01/2019 2 | 8 | 11/01/2019 | Null ,但这只会以我使用它的方式提取1条记录:

top 1

这将使用select top 1 clientid, statusid, datestarted, dateended from ClientStatusHistory where dateended is not null order by id desc 将它们从最新到最旧排序,然后将其拉到当前有效的那个之前,因为我们忽略了空值。

如何扩展上面的查询,以从ClientStatusHistory中提取所有行,其中状态为每desc的行前有null DateEnded字段的行?< / p>

4 个答案:

答案 0 :(得分:3)

您想要row_number()

select top (1) with ties cs.*
from ClientStatusHistory cs
where dateended is not null
order by row_number() over (partition by ClientID  order by id desc);

答案 1 :(得分:3)

使用CROSS/OUTER APPLY的另一种解决方案:

;WITH AvailableClients AS
(
    SELECT DISTINCT C.ClientID FROM ClientStatusHistory AS C
)
SELECT
    C.ClientID,
    T.*
FROM
    AvailableClients AS C
    OUTER APPLY (
        SELECT TOP 1
            H.*
        FROM
            ClientStatusHistory AS H
        WHERE
            C.ClientID = H.CLientID AND
            H.DateEnded IS NOT NULL
        ORDER BY
            H.DateEnded DESC) AS T

CROSS/OUTER APPLY基本上是一种“运行中的 结果集功能,您可以编写该函数,从而有机会链接来自另一个结果集的列(在这种情况下为客户列表)。您可以为此使用TOPORDER BY

CROSSOUTER之间的区别类似于INNERLEFT(加入)。

答案 2 :(得分:1)

一种方法使用窗口函数。但是我认为join也可以:

select csh_prev.*
from ClientStatusHistory csh join
     ClientStatusHistory csh_prev
     on csh.clientid = csh_prev.clientid and
        csh.datestarted = csh_prev.dateended
where csh.dateended is null;

具有窗口功能:

select csh.*
from (select csh.*,
             lead(dateended) over (partition by clientid order by datestarted) as next_dateended
      from ClientStatusHistory csh 
     ) csh
where next_dateended is null;

答案 3 :(得分:0)

使用row_number窗口功能

select * from    
(
select *,row_number() over(partition by ClientID order by DateEnded desc) rn
from t
) where t.rn=1