如何按行获取唯一值-SQL Server

时间:2019-01-18 13:12:37

标签: sql sql-server

我想计算id(sut到sut1)之间的分钟差,但是我不知道如何在SQL Server中做到这一点。

现在我的查询结果是该表:

enter image description here

但是我想要这个结果:

enter image description here

我的查询:

select distinct
    sct.SystemUnitTRID as id_sut,
    sct1.SystemUnitTRID as id_sut1,
    sct.ModifiedDateTime as sut,
    sct1.ModifiedDateTime as sut1,
    DATEDIFF(minute, sct.ModifiedDateTime, sct1.ModifiedDateTime) as diff
from 
    systemunittransactions sct
    left join SystemUnitTransactions sct1 on sct1.ServiceTag = 
    sct.ServiceTag
where 
    sct.servicetag = 'IDXXX12' 
    and sct1.ServiceTag = 'IDXX12' 
    and sct.StatusType = 'STATUS_1'
    and sct1.StatusType = 'STATUS_1'
    and sct.SystemUnitTRID != sct1.SystemUnitTRID
order by 
    sct.SystemUnitTRID

5 个答案:

答案 0 :(得分:3)

我认为您可能想使用此代码。首先,您要创建一个CTE,并使用group by。之后,您需要计算差异:

USE YourDB;
WITH Cte AS 
(
     SELECT Sct.Systemunittrid AS Id_Sut,
            Sct1.Systemunittrid AS Id_Sut1,
            MIN(Sct.Modifieddatetime) AS Sut,
            MAX(Sct1.Modifieddatetime) AS Sut1
     FROM Systemunittransactions AS Sct
       LEFT JOIN Systemunittransactions AS Sct1 ON Sct1.Servicetag = Sct.Servicetag
     WHERE Sct.Servicetag = 'IDXXX12'
           AND Sct1.Servicetag = 'IDXX12'
           AND Sct.Statustype = 'STATUS_1'
           AND Sct1.Statustype = 'STATUS_1'
           AND Sct.Systemunittrid != Sct1.Systemunittrid
     GROUP BY Sct.Systemunittrid,
              Sct1.Systemunittrid 
)

SELECT *, DATEDIFF(minute, Sct.Modifieddatetime, Sct1.Modifieddatetime) AS Diff
FROM Cte;

答案 1 :(得分:2)

如果您使用的是SQL Server 2012或更高版本,则可以根据需要使用LAG或LEAD函数

select distinct
    SystemUnitTRID as id_sut,
    lead(SystemUnitTRID) over (order by systemunittrid) as id_sut1,
    ModifiedDateTime as sut,
    lead(ModifiedDateTime) over (order by systemunittrid) as sut1,
    DATEDIFF(minute, lead(ModifiedDateTime) over (order by systemunittrid), ModifiedDateTime) as diff
from 
    systemunittransactions sct
where 
    servicetag = 'IDXXX12'
and statustype = 'STATUS_1'
order by 
    SystemUnitTRID

答案 2 :(得分:1)

您的示例有问题,您通过serviceTag加入

Systemunittransactions AS Sct
       LEFT JOIN Systemunittransactions AS Sct1 ON Sct1.Servicetag = Sct.Servicetag

但是之后,您将在每个表上通过两个不同的标记进行过滤,

Sct.Servicetag = 'IDXXX12' AND Sct1.Servicetag = 'IDXX12',

一个比另一个多一个X。与该过滤器的联接将永远无法工作。 假设问题中缺少字母错误,并且给出的表格示例中没有多行具有相同对ID的行,则您要查找的查询是:

select 
    sct.SystemUnitTRID as id_sut,
    sct1.SystemUnitTRID as id_sut1,
    sct.ModifiedDateTime as sut,
    sct1.ModifiedDateTime as sut1,
    DATEDIFF(minute, sct.ModifiedDateTime, sct1.ModifiedDateTime) as diff
from 
    systemunittransactions sct
    left join SystemUnitTransactions sct1 on sct1.ServiceTag = 
    sct.ServiceTag and sct.StatusType = sct1.StatusType
where 
    sct.servicetag = 'IDXXX12'  
    and sct.StatusType = 'STATUS_1'
    and sct.SystemUnitTRID != sct1.SystemUnitTRID
order by 
    sct.SystemUnitTRID

答案 3 :(得分:1)

如果此处其他答案不能同时使用laglead,则可以通过创建row_number和{{1} {1}}并按ServiceTag对其进行排序,您可以通过partitionModifiedDateTime join将数据ServiceTag本身获取每行之间的句点。您会注意到,这适用于多个row_number值:

ServiceTag

输出

declare @t table(ServiceTag varchar(20), StatusType varchar(20), SystemUnitTRID int, ModifiedDateTime datetime);
insert into @t values
 ('IDXXX12','STATUS_1',145818840,'2019/01/18 08:35:27')
,('IDXXX12','STATUS_1',145820934,'2019/01/18 08:50:41')
,('IDXXX12','STATUS_1',145822116,'2019/01/18 08:59:18')
,('IDXXX12','STATUS_1',145825658,'2019/01/18 09:23:23')
,('IDXXX12','STATUS_1',145826849,'2019/01/18 09:30:55')
,('IDXXX13','STATUS_1',245818840,'2019/01/17 18:35:00')
,('IDXXX13','STATUS_1',245820934,'2019/01/17 18:50:00')
,('IDXXX13','STATUS_1',245822116,'2019/01/17 18:59:00')
,('IDXXX13','STATUS_1',245825658,'2019/01/17 19:23:00')
,('IDXXX13','STATUS_1',245826849,'2019/01/17 21:30:00')
,('IDXXX14','STATUS_2',345818840,'2019/01/16 18:35:00')
,('IDXXX14','STATUS_2',345820934,'2019/01/16 18:50:00')
,('IDXXX14','STATUS_2',345822116,'2019/01/16 18:59:00')
,('IDXXX14','STATUS_2',345825658,'2019/01/16 19:23:00')
,('IDXXX14','STATUS_2',345826849,'2019/01/16 19:30:00')
;

with d as
(
    select ServiceTag
            ,StatusType
            ,SystemUnitTRID
            ,ModifiedDateTime
            ,row_number() over (partition by ServiceTag order by ModifiedDateTime) as rn
    from @t
    where StatusType = 'STATUS_1'
)
select d.ServiceTag
    ,d.SystemUnitTRID as id_sut
    ,d2.SystemUnitTRID as id_sut1
    ,d.ModifiedDateTime as sut
    ,d2.ModifiedDateTime as sut1
    ,datediff(minute,d.ModifiedDateTime,d2.ModifiedDateTime) as MinuteBoundaries    -- Returns the number of minute boundaries crossed
    ,datediff(second,d.ModifiedDateTime,d2.ModifiedDateTime)/60 as WholeMinutes -- Returns the number of whole minutes
    ,right('00' + cast(datediff(second,d.ModifiedDateTime,d2.ModifiedDateTime)/60/60 as varchar(10)),2)
        + ':'
        + right('00' + cast(datediff(second,d.ModifiedDateTime,d2.ModifiedDateTime)/60%60 as varchar(10)),2) as FormattedTime
from d
    join d as d2
        on d.ServiceTag = d2.ServiceTag
            and d.rn = d2.rn-1
order by d.ServiceTag
        ,d.ModifiedDateTime;

答案 4 :(得分:0)

尝试以下方法:-{select * from(select sct.SystemUnitTRID as id_sut, sct1.SystemUnitTRID as id_sut1, sct.ModifiedDateTime as sut, sct1.ModifiedDateTime as sut1, DATEDIFF(minute, sct.ModifiedDateTime, sct1.ModifiedDateTime) as diff, ROW_NUMBER() over(partition by sct.SystemUnitTRID order by sct.SystemUnitTRID) as rownum from systemunittransactions sct left join SystemUnitTransactions sct1 on sct1.ServiceTag = sct.ServiceTag where sct.servicetag = 'IDXXX12'and sct1.ServiceTag = 'IDXX12' and sct.StatusType = 'STATUS_1'and sct1.StatusType = 'STATUS_1'and sct.SystemUnitTRID != sct1.SystemUnitTRID)t where rownum=1