SQL - 包括拥有最新所有权的群组
SQL - Including groups with most recent ownership
我的数据集包括对自有设备的测试,但可以购买和转售设备,我们只需要与最近所有权相关联的测试。
数据集如下所示:
TestID ProductID RegistrationID TestDate
00021357916020 P3K25EL141297 89D617 2019-07-22
00021357915928 P3K25EL141297 89D617 2019-07-15
00021353422334 P3K25EL141297 5PKY90 2019-05-31
我需要改进以仅包括注册号 89D617 的测试,因为这些测试的所有权最近。我们没有提供任何所有权更改的参考信息,并且注册 ID 没有按有意义的顺序增加,所以我一直无法想出对这些进行分组的方法。
澄清一下 - table 需要包括 RegistrationID 为 89D617 的两个条目,因为这些都是最近注册的测试。
您似乎想要 RegistrationID
每个 ProductID
具有最新 TestDate
的行。如果是这样,一个简单的选择是使用相关子查询进行过滤;
select t.*
from mytable t
where t.RegistrationID = (
select top (1) RegistrationID
from mytable t1
where t1.ProductID = t.ProductID
order by TestDate desc
)
此查询将利用 (RegistrationID, testDate)
上的索引。
DECLARE @t TABLE(TestID NVARCHAR(50),
ProductID NVARCHAR(50),
RegistrationID NVARCHAR(50),
TestDate DATETIME);
INSERT INTO @t
VALUES
('00021357916020','P3K25EL141297','89D617','2019-07-22'),
('00021357915928','P3K25EL141297','89D617','2019-07-15'),
('00021353422334','P3K25EL141297','5PKY90','2019-05-31');
-- Or like this...
SELECT
t1.*
FROM
@t t1
CROSS APPLY
(SELECT TOP 1 RegistrationID
FROM @t
WHERE ProductID = t1.ProductID
ORDER BY TestDate DESC) t2
WHERE
t2.RegistrationID = t1.RegistrationID;
具有FIRST_VALUE()
window功能:
SELECT t.TestID, t.ProductID, t.RegistrationID, t.TestDate
FROM (
SELECT *, FIRST_VALUE(RegistrationID) OVER (PARTITION BY ProductID ORDER BY TestDate DESC) reg
FROM tablename
) t
WHERE t.RegistrationID = t.reg
参见demo。
结果:
> TestID | ProductID | RegistrationID | TestDate
> :---------- | :------------ | :------------- | :---------
> 21357916020 | P3K25EL141297 | 89D617 | 2019-07-22
> 21357915928 | P3K25EL141297 | 89D617 | 2019-07-15
我的数据集包括对自有设备的测试,但可以购买和转售设备,我们只需要与最近所有权相关联的测试。
数据集如下所示:
TestID ProductID RegistrationID TestDate
00021357916020 P3K25EL141297 89D617 2019-07-22
00021357915928 P3K25EL141297 89D617 2019-07-15
00021353422334 P3K25EL141297 5PKY90 2019-05-31
我需要改进以仅包括注册号 89D617 的测试,因为这些测试的所有权最近。我们没有提供任何所有权更改的参考信息,并且注册 ID 没有按有意义的顺序增加,所以我一直无法想出对这些进行分组的方法。
澄清一下 - table 需要包括 RegistrationID 为 89D617 的两个条目,因为这些都是最近注册的测试。
您似乎想要 RegistrationID
每个 ProductID
具有最新 TestDate
的行。如果是这样,一个简单的选择是使用相关子查询进行过滤;
select t.*
from mytable t
where t.RegistrationID = (
select top (1) RegistrationID
from mytable t1
where t1.ProductID = t.ProductID
order by TestDate desc
)
此查询将利用 (RegistrationID, testDate)
上的索引。
DECLARE @t TABLE(TestID NVARCHAR(50),
ProductID NVARCHAR(50),
RegistrationID NVARCHAR(50),
TestDate DATETIME);
INSERT INTO @t
VALUES
('00021357916020','P3K25EL141297','89D617','2019-07-22'),
('00021357915928','P3K25EL141297','89D617','2019-07-15'),
('00021353422334','P3K25EL141297','5PKY90','2019-05-31');
-- Or like this...
SELECT
t1.*
FROM
@t t1
CROSS APPLY
(SELECT TOP 1 RegistrationID
FROM @t
WHERE ProductID = t1.ProductID
ORDER BY TestDate DESC) t2
WHERE
t2.RegistrationID = t1.RegistrationID;
具有FIRST_VALUE()
window功能:
SELECT t.TestID, t.ProductID, t.RegistrationID, t.TestDate
FROM (
SELECT *, FIRST_VALUE(RegistrationID) OVER (PARTITION BY ProductID ORDER BY TestDate DESC) reg
FROM tablename
) t
WHERE t.RegistrationID = t.reg
参见demo。
结果:
> TestID | ProductID | RegistrationID | TestDate
> :---------- | :------------ | :------------- | :---------
> 21357916020 | P3K25EL141297 | 89D617 | 2019-07-22
> 21357915928 | P3K25EL141297 | 89D617 | 2019-07-15