SQL中最接近当前日期的日期(之前日期或未来日期)

时间:2017-10-03 15:17:57

标签: sql sql-server date

我在查找如何查找最接近当前日期的日期时遇到了一些问题。我和其他人一起看了这个: Get closest date to current date sql

我也看了一下:https://bytes.com/topic/sql-server/answers/79502-get-closest-date

我正在使用MS SQL 2012,并且有很多问题要问这个问题,所以我为重新启动它而道歉。我似乎无法让我的查询工作。

基本上我有一张表如下:

ITEMNMBR | MINDATE    | MAXDATE    | CLOSESTDATE
------------------------------------------------
123456   | 2017-10-15 | 2017-11-04 | NULL
654321   | 2017-09-29 | 2017-12-08 | NULL

目前的日期是今天,2017-10-03'我们会找到项目编号' 123456'最近的购买日期是2017-10-15。对于商品编号' 654321'最近的购买日期是2017-09-29,因为最近发生的事情比下次购买生效需要多长时间(因此我看的是日期之间差异的绝对值)。你必须原谅我,但我所包含的查询并不包含" CLOSESTDATE"柱。我已将其包含在那里,以告知您我的任何计算都将该列设为NULL。所以这就是我所拥有的:

--Lines commented below are not used in the current iteration of the query
--DECLARE @dt DATETIME
--SET @dt = GETDATE()

SELECT
    I.ITEMNMBR,
    MIN(PDATE1) AS MINDATE,
    MAX(PDATE1) AS MAXDATE
FROM dbo.IV00101 I 
LEFT OUTER JOIN
    (SELECT P.[Item Number], 
    P.[Req Date] AS PDATE1 
    FROM dbo.Purchases P
    WHERE ((P.[Document Status] = 'Open') AND 
    (P.[POStat] <> 'Closed') AND 
    (P.[POStat] <> 'Received')) AND P.[Req Date] >= DATEADD(d, -15, 
    DATEDIFF(d, 0, GETDATE()))
    ) AS P ON P.[Item Number]= I.ITEMNMBR
WHERE P.[Item Number] = '123456'
GROUP BY 
    I.ITEMNMBR
ORDER BY MINDATE DESC

当我运行此查询时,我得到了我之前概述的表格,减去了&#34; CLOSESTDATE&#34;柱。 &#34; CLOSESTDATE&#34;列是我想用来显示最接近今天的购买日期。基本上,如果购买日期发生在三天前,而下一个购买日期是一个月,那么我想显示三天前的购买日期。此外,可以在不使用子查询的情况下编写查询,但在恢复到相当简单的原始查询之前,我在子查询中使用了其他计算。因此,查询可以这样写:

SELECT
    I.ITEMNMBR,
    MIN(P.[Req Date]) AS MINDATE,
    MAX(P.[Req Date]) AS MAXDATE
FROM dbo.IV00101 I 
LEFT OUTER JOIN
    Purchases P ON P.[Item Number] = I.ITEMNMBR
WHERE P.[Item Number] = '123456' ((P.[Document Status] = 'Open') AND 
    (P.[POStat] <> 'Closed') AND 
    (P.[POStat] <> 'Received')) AND P.[Req Date] >= DATEADD(d, -15, 
    DATEDIFF(d, 0, GETDATE()))
GROUP BY 
    I.ITEMNMBR
ORDER BY MINDATE DESC

最后,正如您所看到的,我在过去15天内有一个日期约束条件,因此任何比这更早的内容都不会显示出来。

非常感谢提前!

3 个答案:

答案 0 :(得分:3)

我仍然不太了解你的问题,但我希望这会给你一个开始,你可以试试rextester样本here

但对我来说,你需要一个简单的案例陈述:

select ITEMNMBR
       ,case when abs(datediff(day, MINDATE, convert(date,getdate()))) > abs(datediff(day, MAXDATE, convert(date,getdate()))) then 'MINDATE is greater' else 'MAXDATE is greater' end as ClosestDate
from myTable

如果您有任何疑问,请告诉我。我很乐意提供帮助。

答案 1 :(得分:2)

我已经采用了您的数据和架构,并对我认为您的基础数据的实际情况进行了近似估算。从那以后,你的问题实际上非常简单:

declare @t table(ItemNumber int, ReqDate datetime, DocumentStatus nvarchar(100), POStat nvarchar(100))
insert into @t values
 (123456,'2017-10-15','Open','Not Closed')
,(123456,'2017-11-04','Open','Not Closed')
,(654321,'2017-09-29','Open','Not Closed')
,(654321,'2017-12-08','Open','Not Closed')

,(123456,'2017-10-11','Open','Closed')
,(123456,'2017-11-01','Closed','Not Closed')
,(654321,'2017-09-21','Closed','Not Closed')
,(654321,'2017-12-01','Open','Received');

select t.ItemNumber
      ,min(t.ReqDate) as MinDate
      ,max(t.ReqDate) as MaxDate

            -- Find the difference in days for both Min and Max dates, converting to positive numbers where negative,
      ,case when abs(datediff(d,min(t.ReqDate),getdate())) < abs(datediff(d,max(t.ReqDate),getdate()))
            then min(t.ReqDate)         -- And then return the appropriate one.
            else max(t.ReqDate)
            end as ClosestDate
from @t t
where t.DocumentStatus = 'Open'
    and t.POStat not in('Closed','Received')
    and t.ReqDate >= dateadd(d,-15,cast(getdate() as date))
group by t.ItemNumber
order by MinDate desc;

输出:

+------------+-------------------------+-------------------------+-------------------------+
| ItemNumber |         MinDate         |         MaxDate         |       ClosestDate       |
+------------+-------------------------+-------------------------+-------------------------+
|     123456 | 2017-10-15 00:00:00.000 | 2017-11-04 00:00:00.000 | 2017-10-15 00:00:00.000 |
|     654321 | 2017-09-29 00:00:00.000 | 2017-12-08 00:00:00.000 | 2017-09-29 00:00:00.000 |
+------------+-------------------------+-------------------------+-------------------------+

答案 2 :(得分:0)

使用以下命令更改查询的初始部分:

SELECT DISTINCT
I.ITEMNMBR,
MIN(PDATE1) AS MINDATE,
MAX(PDATE1) AS MAXDATE
IF(ABS(DATEDIFF(MIN(PDATE1)-SYSDATETIME())) > 
ABS(DATEDIFF(MAX(PDATE1)-SYSDATETIME())),
MAX(PDATE1),MIN(PDATE1)) as CLOSESTDATE