Sql 从最小日期获取最大日期时间值
我的表格有零件号、零件序列号、零件测试号、零件测试结果和零件测试日期。这些键是零件号、零件序列号、零件测试号和零件测试日期。零件在同一天的不同日期和不同时间使用相同的序列号和测试编号进行测试。我想看看测试的第一天和那天的最后结果。我想创建一个视图。可以有不同的零件号,每个零件号可以有不同的序列号。每个零件编号与不同的试验编号相关联 以下是特定零件号、序列号和测试的结果 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 我想创建一个视图,其中包含每个序列号的所有零件号,以及第一次测试时的测试号 非常感谢您的帮助 如果我通过序列号,则会得到所需的结果: 声明@DATE DATETIME27; 声明@TOPDATE DATETIME27; 声明@MAXDATE DATETIME27; 从数据序列= “UNLDR598”; 选择@TOPDATE=dateaddhh,23,@DATE 从数据字段中选择@MAXDATE=maxDATA\u Date\u Time,其中 数据日期时间>@日期和数据日期时间<@TOPDATE和 数据_串行='UNLDR598' 选择数据部件、数据串行、数据测试、数据值、数据日期时间 从数据字段 其中DATA_Serial='UNLDR598' 数据\日期\时间=@MAXDATESql 从最小日期获取最大日期时间值,sql,sql-server,Sql,Sql Server,我的表格有零件号、零件序列号、零件测试号、零件测试结果和零件测试日期。这些键是零件号、零件序列号、零件测试号和零件测试日期。零件在同一天的不同日期和不同时间使用相同的序列号和测试编号进行测试。我想看看测试的第一天和那天的最后结果。我想创建一个视图。可以有不同的零件号,每个零件号可以有不同的序列号。每个零件编号与不同的试验编号相关联 以下是特定零件号、序列号和测试的结果 part number serial number TEST # DATE test-value 555-9
您可以使用两个窗口函数来实现这一点
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)
泰国人回答了我的要求,我想看看它测试的第一天和那天的最后一个结果,它与你的样本输出不匹配
要获得预期输出的倒数第二个,请使用以下方法:
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
只是为了好玩,我用普通的表表达式做了。从理论上讲,这将有助于找到每个试验编号的所有零件和序列号组合的第一个日期的最后时间 Base DataThank@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)
然后我用CTEs做了。首先,我找到了最短日期,然后是最长时间,然后把它们放在一起:
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
上一次测试的时间和日期不是。。。1/17/19 0:17? 我对这个问题的理解是:他们在寻找测试第一天的最后一次。因此,您需要找到测试第一天的日期,然后找到该日期的最后一次测试。在这种情况下,11/30/18 10:22不是该日期的最后一次测试,而不是11/30/18 9:22。因此我感到困惑,因为这有点不清楚。@arahman,很公平,我没有仔细看,因为我没有看到。这个问题的措辞令人困惑。@NickA我同意,这让我很困惑。我只是好奇,这会给你上面问题中给出的输出,还是会给你日期为:11/30/18 10:22的行。样本表中的第5行。不是要求的输出,而是回答了问题,正如你们所说的,这与@arahman相矛盾,但我也提供了解决方案。我同样认为,这将与OP在其回答中显示的输出不同。好吧,我添加了一个修复,但他们可能只是搞错了问题@arahmand,我很难读懂这个未格式化的问题,但我的代码是有效的,所以你所要做的就是更改表名@tresaaBTW。如果有多条记录具有第一天的最后一个时间,则可能会出现问题。查询提供了第一天的最后一个值的结果,但也提供了其他天的所有结果。有什么办法可以解决吗?谢谢,我做了一些修改。谢谢:我如何用最少的时间加上八个小时获得相同的信息,而不是用最少的一天中的最大值。换句话说,目前我们正在选择最小日的最大值,但如果我想在最小时间的正确小时后得到该值。
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