繁体   English   中英

从最小日期获取最大日期时间值

[英]Get the MAX datetime value from the MIN date

我的表有零件号、零件序列号、零件测试号、零件测试结果和零件测试日期。 键是零件号、零件序列号、零件测试号和零件测试日期。 一个零件在同一天的不同日期和不同时间使用相同的序列号和测试号进行测试。 我想看看它测试的第一天和那天的最后一个结果。 我想创建一个视图。 可以有不同的部件号,每个部件号可以有不同的序列号。 每个零件编号与不同的测试编号相关联

以下是特定部件号、序列号、测试的结果

part number serial number   TEST #       DATE   test-value
555-99          abcd123         10  11/30/18 2:02   0
555-99          abcd123         10  11/30/18 2:22   13714.66797
555-99          abcd123         10  11/30/18 2:23   2
555-99          abcd123         10  11/30/18 9:22   5
555-99          abcd123         10  11/30/18 10:22  14809.70703
555-99          abcd123         10  1/9/19 6:13 14574.62891
555-99          abcd123         10  1/9/19 6:14 14084.62891
555-99          abcd123         10  1/9/19 14:53    14119.66797
555-99          abcd123         10  1/9/19 14:54    13874.72656
555-99          abcd123         10  1/9/19 14:53    14844.74609
555-99          abcd123         10  1/11/19 7:19    15404.76563
555-99          abcd123         10  1/15/19 17:47   14179.76563
555-99          abcd123         10  1/17/19 0:17    14214.64844
555-99          abcd123         10  1/17/19 0:17    14216.64944

输出应该是

555-99  abcd123 10  11/30/18 9:22   5

我想创建一个视图,其中包含每个序列号的所有部件号及其上次测试时的测试号。

任何帮助是极大的赞赏。

如果我通过序列号,这会给出所需的结果:

 DECLARE @DATE DATETIME2(7); DECLARE @TOPDATE DATETIME2(7); DECLARE @MAXDATE DATETIME2(7); SELECT @Date = MIN(DATA_Date_Time) FROM DATA_Fields WHERE DATA_Serial = 'UNLDR598' ; SELECT @TOPDATE = dateadd(hh, 23, @DATE) select @MAXDATE =max(DATA_Date_Time )from DATA_Fields where DATA_Date_Time > @DATE AND DATA_Date_Time < @TOPDATE AND DATA_Serial = 'UNLDR598' SELECT DATA_PART,DATA_SERIAL, DATA_TEST, data_value ,DATA_Date_Time FROM DATA_Fields where DATA_Serial = 'UNLDR598' AND DATA_Date_Time = @MAXDATE <br>

您可以使用两个窗口函数来实现这一点。

declare @table table ([part number] varchar(6), [serial number] varchar(16),   [TEST #] int,  [DATE] datetime,  [test-value] decimal(10,5))
insert into @table
values
('555-99','abcd123',10,'11/30/18 2:02',0),
('555-99','abcd123',10,'11/30/18 2:22',13714.66797),
('555-99','abcd123',10,'11/30/18 2:23',2),
('555-99','abcd123',10,'11/30/18 9:22',5),
('555-99','abcd123',10,'11/30/18 10:22',14809.70703),
('555-99','abcd123',10,'1/9/19 6:13',14574.62891),
('555-99','abcd123',10,'1/9/19 6:14',14084.62891),
('555-99','abcd123',10,'1/9/19 14:53',14119.66797),
('555-99','abcd123',10,'1/9/19 14:54',13874.72656),
('555-99','abcd123',10,'1/9/19 14:53',14844.74609),
('555-99','abcd123',10,'1/11/19 7:19',15404.76563),
('555-99','abcd123',10,'1/15/19 17:47',14179.76563),
('555-99','abcd123',10,'1/17/19 0:17',14214.64844),
('555-99','abcd123',10,'1/17/19 0:17',14216.64944)

select top 1 with ties * 
from
(
    select 
        *
        ,FirstDay = dense_rank() over (partition by [part number], [serial number], [TEST #] order by cast([DATE] as date))
    from @table
) x
where FirstDay = 1
order by row_number() over (partition by [part number], [serial number], [TEST #] order by [DATE] desc) 

Thais 回答了我想在测试的第一天和当天的最后一个结果您的样本输出不匹配的请求。

要获得您预期输出的倒数第二个,请使用以下内容:

select * 
from(
    select 
        *
        ,RN = row_number() over (partition by [part number], [serial number], [TEST #] order by [DATE] desc)
    from
        (
        select 
            *
            ,FirstDay = dense_rank() over (partition by [part number], [serial number], [TEST #] order by cast([DATE] as date))
        from @table
        ) x
    where FirstDay = 1
) y
where RN = 2

这是一个脚本,它可以解决问题。 它不是那么优雅,但应该工作得更快。

SELECT yt.*
FROM #YourTable AS yt
OUTER APPLY (
    SELECT md = MIN(CAST(i.[DATE] AS date)) FROM #YourTable AS i
    WHERE i.[part number] = yt.[part number]
        AND i.[serial number] = yt.[serial number]
        AND i.[TEST #] = yt.[TEST #]
) AS MinDate
OUTER APPLY (
    SELECT MT = MAX(i.[DATE]) FROM #YourTable AS i
    WHERE i.[part number] = yt.[part number]
        AND i.[serial number] = yt.[serial number]
        AND i.[TEST #] = yt.[TEST #]
        AND CAST(i.[DATE] AS date) = MinDate.MD
) AS MaxTime
WHERE yt.DATE = MaxTime.MT

只是为了好玩,我用普通的表表达式做了它。 从理论上讲,这应该可以找到每个测试编号的零件和序列号的所有组合的第一个日期的最后时间。

基础数据(感谢@scsimon 提供的代码):

CREATE TABLE #TestTable (part_number varchar(10), serial_number varchar(20), TESTnum int,  Tdate datetime,  Test_Value decimal(10,5))
insert into #TestTable
values
('555-99','abcd123',10,'11/30/18 2:02',0),
('555-99','abcd123',10,'11/30/18 2:22',13714.66797),
('555-99','abcd123',10,'11/30/18 2:23',2),
('555-99','abcd123',10,'11/30/18 9:22',5),
('555-99','abcd123',10,'11/30/18 10:22',14809.70703),
('555-99','abcd123',10,'1/9/19 6:13',14574.62891),
('555-99','abcd123',10,'1/9/19 6:14',14084.62891),
('555-99','abcd123',10,'1/9/19 14:53',14119.66797),
('555-99','abcd123',10,'1/9/19 14:54',13874.72656),
('555-99','abcd123',10,'1/9/19 14:53',14844.74609),
('555-99','abcd123',10,'1/11/19 7:19',15404.76563),
('555-99','abcd123',10,'1/15/19 17:47',14179.76563),
('555-99','abcd123',10,'1/17/19 0:17',14214.64844),
('555-99','abcd123',10,'1/17/19 0:17',14216.64944)

然后我使用 CTE 做到了。 首先我找到了最小日期,然后是最大时间,然后把它们放在一起:

WITH CTE AS
    (SELECT tt.part_number
           ,tt.serial_number
           ,tt.TESTnum
           ,MIN(CAST(tt.Tdate as DATE)) AS MinDate
     FROM #TestTable tt
     GROUP BY tt.part_number, tt.serial_number, tt.TESTnum),

     CTE1 AS
     (SELECT tt.part_number
            ,tt.serial_number
            ,tt.TESTnum
            ,MAX(tt.Tdate) AS Date1
      FROM #TestTable tt 
      JOIN CTE c ON tt.part_number = c.part_number
             AND tt.serial_number = c.serial_number
             AND tt.TESTnum = c.TESTnum
      WHERE c.MinDate = CAST(tt.Tdate as DATE)
      GROUP BY tt.part_number, tt.serial_number, tt.TESTnum)

SELECT   t.part_number
        ,t.serial_number
        ,t.TESTnum
        ,T.Tdate
        ,t.Test_Value
FROM #TestTable t
JOIN cte1 c ON t.part_number = c.part_number
            AND t.serial_number = c.serial_number
            AND t.TESTnum = c.TESTnum
WHERE Tdate = c.date1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM