在另一列中选择具有相同ID但值不同的行-SQL Server

时间:2019-05-22 19:08:06

标签: sql-server

我有一张表格,该表格显示了正在分析的证据的监管链。证据可以只在一个位置进行分析,但也可以转移到不同的实验室进行分析。我正在尝试编写一个查询,以返回在不同实验室中进行分析的案例编号。

以下是数据的示例:CaseNumber 1从化学实验室开始,然后转移到DNA实验室,然后转移回化学实验室。情况2仅与化学实验室相关(不需要在查询结果中看到此情况)。

ID   CaseNumber     Lab        ActionDate   Action
-------------------------------------------------------------------
1     1             Chem       1/1/2019     case created
2     1             Chem       1/2/2019     container created
3     1             DNA        2/1/2019     container routed to DNA
4     1             DNA        2/3/2019     evidence analyzed
5     1             Chem       2/3/2019     edit route
6     2             Chem       2/4/2019     create case
7     2             Chem       2/5/2019     analyze evidence

这是我到目前为止所拥有的。这将返回案例编号和唯一的实验室,但我想以某种方式合并ActionDate来显示将其路由到新位置的实际日期。

SELECT DISTINCT
    casenumber, lab 
FROM 
    summary 
WHERE 
    casenumber IN (SELECT a.casenumber 
                   FROM summary a
                   JOIN summary b on b.casenumber = a.casenumber AND b.lab <> a.lab)
    AND actiondate BETWEEN '2019-01-02' AND '2019-01-04'
ORDER BY
    casenumber

我希望查询结果如下所示。我想查看每个实验室的第一个条目(因为这是它实际路由到新位置的日期)

ID   CaseNumber     Lab        ActionDate   Action
-------------------------------------------------------------------
1     1              Chem       1/1/2019    case created
3     1              DNA        2/1/2019    container routed to DNA
5     1              Chem       2/3/2019    container routed to Chem

1 个答案:

答案 0 :(得分:0)

有很多方法可以做到这一点,这是其中一种。请注意,这仅适用于sql server 2012+。

create table #Something
(
    ID int
    , CaseNumber int
    , Lab varchar(10)
    , ActionDate date
    , Action varchar(50)
)

insert #Something values
(1, 1, 'Chem', '1/1/2019', 'case created')
, (2, 1, 'Chem', '1/2/2019', 'container created')
, (3, 1, 'DNA', '2/1/2019', 'container routed to DNA')
, (4, 1, 'DNA', '2/3/2019', 'evidence analyzed')
, (5, 1, 'Chem', '2/3/2019', 'edit route')
, (6, 2, 'Chem', '2/4/2019', 'create case')
, (7, 2, 'Chem', '2/5/2019', 'analyze evidence')
;

with SortedResults as
(
    select s.ID
        , s.CaseNumber
        , s.Lab
        , s.ActionDate
        , Action = case when LAG(Lab, 1) over(partition by CaseNumber order by ActionDate) is null then Action 
            when LAG(Lab, 1) over(partition by CaseNumber order by ActionDate) = Lab then NULL
            else 'container routed to ' + Lab end
    from #Something s
)

select *
from SortedResults
where Action > ''
order by CaseNumber, ActionDate

drop table #Something