Sql server 查找两个最近的可比较日期(相同的工作日和月份)
我试过寻找,但运气不好。我想做的是根据任何输入日期,得到两个最新的日期,它们与输入日期在同一个月的同一天和同一个工作日 例如,2018年7月2日(dd/mm/yyyy)应返回2018年4月2日和2017年10月2日,因为这两个日期都是第二个星期一,也是最近发生的两个 我有一个日期表,我可以与之合作,我正在考虑做一个自己加入得到这个,但我会感谢一些帮助Sql server 查找两个最近的可比较日期(相同的工作日和月份),sql-server,date,sql-server-2012,Sql Server,Date,Sql Server 2012,我试过寻找,但运气不好。我想做的是根据任何输入日期,得到两个最新的日期,它们与输入日期在同一个月的同一天和同一个工作日 例如,2018年7月2日(dd/mm/yyyy)应返回2018年4月2日和2017年10月2日,因为这两个日期都是第二个星期一,也是最近发生的两个 我有一个日期表,我可以与之合作,我正在考虑做一个自己加入得到这个,但我会感谢一些帮助 编辑:忘了提到我正在使用SQL Server 2012如果您有一个日期表,那么您可以使用它。以下伪代码基于ANSI SQL函数,因为日期函数依赖于
编辑:忘了提到我正在使用SQL Server 2012如果您有一个日期表,那么您可以使用它。以下伪代码基于ANSI SQL函数,因为日期函数依赖于数据库:
select d.*
from dates d
where extract(dow from d.date) = extract(dow from date '2018-07-02') and
extract(day from d.date) = extract(day from '2018-07-02') and
d.date < date '2018-07-02'
order by d.date desc
fetch first 2 rows only;
选择d*
从日期d开始
其中摘录(道琼斯指数自d.date起)=摘录(道琼斯指数自“2018-07-02”日起),以及
摘录(从d.日期算起的日期)=摘录(从'2018-07-02'算起的日期)和
d、 日期<日期'2018-07-02'
按日期说明订购
只取前2行;
您的日期表需要计算每一天的星期几(数字)。然后,只需JOIN
ing、排序和挑选前两行即可
MS SQL Server 2017架构设置:
DECLARE @enteredDate date = '2018-07-02' /* This is the date you entered. */
SELECT TOP 2 s1.testDate
FROM (
SELECT t1.testDate
, ROW_NUMBER() OVER ( PARTITION BY t1.testDate ORDER BY t1.testDate DESC, t1.id DESC ) AS rn
FROM t1
INNER JOIN datedim dd ON t1.testDate = dd.theDate
AND dd.theDay = DATEPART(day,@enteredDate)
AND dd.theDOW = DATEPART(weekday,@enteredDate)
) s1
WHERE rn = 1 /* Get 1st result for a date. */
ORDER BY s1.testDate DESC
| testDate |
|------------|
| 2018-04-02 |
| 2017-10-02 |
设置日期表
/********************************CALENDAR********************************/
/*
As always, thank you to Aaron Bertrand for the Calendar Table example.
https://www.mssqltips.com/sqlservertip/4054/creating-a-date-dimension-or-calendar-table-in-sql-server/
*/
SET DATEFIRST 7 ; /* SUNDAY */ /* Make sure the week starts on the same day. */
CREATE TABLE datedim (
theDate date PRIMARY KEY
, theDay AS DATEPART(day, theDate) --int
, theWeek AS DATEPART(week, theDate) --int
, theMonth AS DATEPART(month, theDate) --int
, theYear AS DATEPART(year, theDate) --int
, theDOW AS DATEPART(weekday, theDate) --int
, yyyymmdd AS CONVERT(char(8), theDate, 112) /* yyyymmdd */
) ;
/************************************************************************/
/*
Use the catalog views to generate as many rows as we need. This example
creates a date dimension for 1 Sept 2017 to 1 Aug 2018.
*/
INSERT INTO datedim ( theDate )
SELECT d
FROM (
SELECT d = DATEADD(day, s1.rn - 1, '2017-01-01')
FROM
(
SELECT TOP ( DATEDIFF(day, '2017-01-01', '2018-12-31') )
rn = ROW_NUMBER() OVER (ORDER BY sao.object_id)
FROM sys.all_objects sao
) s1
) s2
/************************************************************************/
设置测试数据
/* TEST DATA */
CREATE TABLE t1 (id int identity, testDate date) ;
INSERT INTO t1 ( testDate )
VALUES
( '2018-04-02' ) /* This */
, ( '2017-10-02' ) /* This */
, ( '2018-04-02' ) /* Duplicate */
, ( '2017-09-27' )
, ( '2018-07-01' )
, ( '2018-05-02' ) /* Same day, Diff DOW */
, ( '2017-09-02' ) /* Same day, Diff DOW */
, ( '2017-10-09' ) /* Diff day, Same DOW */
, ( '2017-01-02' ) /* Same day, Same DOW, Earlier */
, ( null )
;
我添加了几个案例,这些案例将在早期过滤器中被收集,但最终会被过滤掉。请参阅设置中的注释
主查询:
DECLARE @enteredDate date = '2018-07-02' /* This is the date you entered. */
SELECT TOP 2 s1.testDate
FROM (
SELECT t1.testDate
, ROW_NUMBER() OVER ( PARTITION BY t1.testDate ORDER BY t1.testDate DESC, t1.id DESC ) AS rn
FROM t1
INNER JOIN datedim dd ON t1.testDate = dd.theDate
AND dd.theDay = DATEPART(day,@enteredDate)
AND dd.theDOW = DATEPART(weekday,@enteredDate)
) s1
WHERE rn = 1 /* Get 1st result for a date. */
ORDER BY s1.testDate DESC
| testDate |
|------------|
| 2018-04-02 |
| 2017-10-02 |
在主查询中,我们要做的第一件事是使用ROW\u NUMBER()
窗口函数,确保如果存在重复的日期条目,我们只会得到一条记录。如果保证数据没有重复日期,则可以跳过此步骤
[结果][2]:
DECLARE @enteredDate date = '2018-07-02' /* This is the date you entered. */
SELECT TOP 2 s1.testDate
FROM (
SELECT t1.testDate
, ROW_NUMBER() OVER ( PARTITION BY t1.testDate ORDER BY t1.testDate DESC, t1.id DESC ) AS rn
FROM t1
INNER JOIN datedim dd ON t1.testDate = dd.theDate
AND dd.theDay = DATEPART(day,@enteredDate)
AND dd.theDOW = DATEPART(weekday,@enteredDate)
) s1
WHERE rn = 1 /* Get 1st result for a date. */
ORDER BY s1.testDate DESC
| testDate |
|------------|
| 2018-04-02 |
| 2017-10-02 |
我认为这个问题是一个很好的例子,说明了日历表是多么有用。
02/10/2017
在周二。顺便问一下,您使用的是哪种DBMS?您使用的是什么数据库?SQL Server 2012您的日期维度中是否有一周中的某一天?谢谢。这个答案非常详细,帮助我实现了我想要做的事情。