尝试在MAX(日期)的查询中查找TOP

时间:2018-03-05 21:01:22

标签: sql sql-server datetime max

我在查明如何从查询中获取正确的日期时遇到问题。我需要为每个工作号码提取最早的日期,但由于我在子查询中无法获得Order By,因此我不确定要走哪条路线。     --MSSQL 2016

Create Table #FOO
(
    Job varchar(4),
    CurrentMilestone varchar(10),
    MilestoneDate DATETIME
)

INSERT INTO #FOO (Job,CurrentMilestone,MilestoneDate)
    VALUES ('P5','ONSITE','2017-10-23');
INSERT INTO #FOO (Job,CurrentMilestone,MilestoneDate)
    VALUES ('P5','PAINT','2017-11-01');
INSERT INTO #FOO (Job,CurrentMilestone,MilestoneDate)
    VALUES ('P5','SHIP','2018-02-01');
INSERT INTO #FOO (Job,CurrentMilestone,MilestoneDate)
    VALUES ('P5','OFFSITE','2017-12-20');
INSERT INTO #FOO (Job,CurrentMilestone,MilestoneDate)
    VALUES ('P16','BREAK','2017-10-10');
INSERT INTO #FOO (Job,CurrentMilestone,MilestoneDate)
    VALUES ('P16','ONSITE','2017-11-11');
INSERT INTO #FOO (Job,CurrentMilestone,MilestoneDate)
    VALUES ('P16','HACK','2017-12-20');
INSERT INTO #FOO (Job,CurrentMilestone,MilestoneDate)
    VALUES ('P16','SHIP','2018-05-01');

SELECT * FROM #FOO;  

 SELECT f.Job,f.CurrentMilestone, f.MilestoneDate
    FROM (SELECT Job, MAX(MilestoneDate) as MilestoneDate 
        FROM #FOO
        GROUP BY Job
            ) a
 JOIN #FOO f ON a.Job = f.job AND a.MilestoneDate = f.MilestoneDate
 ORDER BY f.MilestoneDate ASC
        IF OBJECT_ID('tempdb..#FOO') IS NOT NULL DROP TABLE #FOO
GO

我的回报应该是这样的:

Job     CurrentMilestone     MilestoneDate
P5      ONSITE               2017-10-23
P16     BREAK                2017-10-10

3 个答案:

答案 0 :(得分:1)

试试这个。如果有问题,请告诉我并找到答案。希望这可以帮助。感谢。

SELECT Job, 
  CurrentMilestone,
  CAST(MilestoneDate as Date) as MilestoneDate
from (
  SELECT Job, 
   CurrentMilestone,
   MilestoneDate,
   row_number() over (partition by job order by MilestoneDate) as rnum 
  FROM #FOO) t
where t.rnum=1

Result:
Job     CurrentMilestone     MilestoneDate
P16     BREAK                2017-10-10    
P5      ONSITE               2017-10-23

答案 1 :(得分:1)

您可以使用TOP 1

简化此操作
SELECT TOP 1
   Job, 
   MilestoneDate
FROM #FOO
ORDER BY MilestoneDate ASC

如果您想按工作要求,请使用ROW_NUMBER()

;with cte as(
select *
RN = row_number() over (partition by Job order by MilestoneDate asc))

select * from cte where RN = 1

如果您在MAX()上出售,我会使用内部联接和派生表来说明。这只是个人偏好。

SELECT
   Job,
   CurrentMilestone,
   MilestoneDate
FROM #FOO F
INNER JOIN (SELECT Job, MIN(MilestoneDate) DT
            FROM #FOO
            GROUP BY Job) F2 ON F2.DT = F.MilestoneDate and F2.Job = F.Job

答案 2 :(得分:1)

SQL Server在没有子查询的情况下有这种很酷的方式:

SELECT TOP (1) WITH TIES f.*
FROM #FOO f
ORDER BY ROW_NUMBER() OVER (PARTITION BY job ORDER BY MilestoneDate);