我需要一个查询,以获得第一个可用日期,向后移动,不包括不可用日期。
示例:
日期必须在2016-05-20之前(此日期是一个变量)。最好的选择是2016-05-19(前一天)。如果这是不可用的,那就提前一天。
不可用日期保存在表中,可以选择如下所示
SELECT blockedDate FROM tbl_BlockedDates
编辑:
我已经看到这样的事情会起作用,但我想不出如何正确地设置它以适应我的情况
SELECT TOP 1 [Date]
FROM (
SELECT TOP (DATEDIFF(DAY, @Date1, @Date2)+1)
[Date] = dateadd(DAY, ROW_NUMBER() OVER(ORDER BY c1.name), @Date1)
FROM [master].[dbo].[spt_values] c1
) D
WHERE D.Date NOT IN (SELECT ClosingDate FROM ClosingDays WHERE IsClosedAllDay = 1)
and Date not in (SELECT blockedDate FROM tbl_BlockedDates )我怎么才能得到我需要的日期?
发布于 2016-05-16 15:15:33
为此需要一个日期表。
Declare @start_date datetime = '2014-01-01',
@varibale_date datetime = '2016-05-20'
;WITH e1(n) AS
(
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
), -- 10
e2(n) AS (SELECT 1 FROM e1 CROSS JOIN e1 AS b), -- 10*10
e3(n) AS (SELECT 1 FROM e1 CROSS JOIN e2), -- 10*100
e4(n) AS (SELECT 1 FROM e3 CROSS JOIN e2),
Tally(n) AS (select ROW_NUMBER() OVER (ORDER BY n) FROM e4),
dates(dt) AS (select DATEADD(dd,n-1,@start_date) from tally)
SELECT TOP 1 dt
FROM dates
WHERE dt < @varibale_date
AND NOT EXISTS (SELECT 1 FROM tbl_blockeddates t
WHERE t.blockeddate = dt)
ORDER BY dt DESC 发布于 2016-05-16 15:20:07
这比听起来要复杂得多,因为你可能会有一连串被封锁的日期,而且必须提前一天。
如果没有阻塞的日期,或者阻塞的日期在所讨论的日期之前有一个空白,这就足够简单了:
with bd as (
select bd.*, max(grp) as maxgrp
from (select bd.*,
dateadd(day, - row_number() over (order by blockeddate), blockeddate) as grp
from tbl_BlockedDates bd
where blockedDate < @Date
) bd
)
select (case when max(blockedDate) is null or
max(blockedDate) <> dateadd(day, -1, @Date)
then dateadd(day, -1, @Date)
else dateadd(day, -1, min(case when grp = maxgrp then blockedDate end))
end) as FreeDate
from bd;else部分是棘手的部分。grp定义了一组连续日期。min()正在获取这样一个组的第一个日期,并在当天减去。
发布于 2016-05-16 15:31:01
DECLARE @DateVariable DATE = '20160520';
SELECT TOP (1)
YT.yourDate
FROM yourTable AS [YT]
WHERE YT.yourDate < @DateVariable
AND NOT EXISTS (SELECT 1 FROM tbl_BlockedDate AS [bd] WHERE bd.blockedDate = YT.yourDate)
ORDER BY
YT.yourDate DESC;这里的一个问题是,您还没有为您的日历表提供DDL语句(如果您没有DDL语句,则Zohar and在您的问题评论中对此提出了一个很好的观点和解决方案)。
但是,如果您确实有一个日历表或一个包含日期的表,那么您可能需要小心其中的多个条目,其中有一个日期与您的tbl_BlockedDate表中不存在的日期相同。
示例
ID | Date |
---------------------
1 | '2016-05-20' |
2 | '2016-05-19' |
3 | '2016-05-19' |
4 | '2016-05-19' |
5 | '2016-05-19' |上面的查询将返回1行,日期为19,但多行满足查询。
如果您将查询更改为包含WITH TIES,它将返回所有4条记录和19条记录,因为它们都满足此查询。
SELECT TOP (1) WITH TIES
YT.yourDate
FROM yourTable AS [YT]
WHERE YT.yourDate < @DateVariable
AND NOT EXISTS (SELECT 1 FROM tbl_BlockedDate AS [bd] WHERE bd.blockedDate = YT.yourDate)
ORDER BY
YT.yourDate DESC;这就是为什么我们建议在您的订单中包括另一个标识列,希望能够消除这个问题。
下面的示例使用合成列ID返回带有Date: '2016-05-19'和ID: 2的行。
SELECT TOP (1)
YT.yourDate
FROM yourTable AS [YT]
WHERE YT.yourDate < @DateVariable
AND NOT EXISTS (SELECT 1 FROM tbl_BlockedDate AS [bd] WHERE bd.blockedDate = YT.yourDate)
ORDER BY
YT.yourDate DESC,
YT.identifying_column ASC;https://stackoverflow.com/questions/37257153
复制相似问题