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

时间:2019-01-22 17:06:39

标签: sql sql-server

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

以下是特定零件号,序列号,测试的结果

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> 

3 个答案:

答案 0 :(得分:1)

您可以使用两个窗口函数来实现此目的。

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) 

泰国人回答了请求我想查看测试的第一天以及该天的最后结果,该结果与您的示例输出不匹配

要获得预期输出的 next to last ,请使用类似以下内容的

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

仅出于乐趣,我使用常见的表表达式进行了此操作。从理论上讲,这应该可以找到每个测试编号的零件和序列号所有组合首次使用日期的最后时间。

基础数据(感谢@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