我尝试搜索时没有多大运气。我要根据输入的日期进行操作,获取两个最近的日期作为输入日期,这些日期具有每月的同一天和同一天。
例如,日期02/02/2018(dd / mm / yyyy)应该返回02/04/2018和02/10/2017,因为它们分别是第二个星期一和最近两次出现。
我有一个可以使用的日期表,我正在考虑自己进行联接以获取此日期,但我希望获得一些帮助。
编辑:忘了提及我正在使用SQL Server 2012
答案 0 :(得分:0)
如果有日期表,则可以使用它。以下基于ANSI SQL函数的伪代码,因为date函数取决于数据库:
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;
答案 1 :(得分:0)
您的日期表需要计算每天的星期几(数字)。然后,只需JOIN
进行排序,排序和选择前2行即可。
MS SQL Server 2017架构设置:
设置日期表
/********************************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
在主查询中,我们要做的第一件事是使用ROW_NUMBER()
窗口函数来确保只有重复的日期条目,我们才能得到一条记录。如果保证您的数据没有重复日期,则可以跳过此步骤。
[结果] [2] :
| testDate |
|------------|
| 2018-04-02 |
| 2017-10-02 |
我认为这个问题是一个很好的例子,说明日历表有多有用。