我需要一个查询来让第一个可用日期向后移动,不包括不可用日期。
示例:
日期必须在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 )
编辑:
我已经看到这样的东西会起作用,但我无法弄清楚如何根据我的情况正确设置
List fragments = getSupportFragmentManager().getFragments();
mCurrentFragment = fragments.get(fragments.size() - 1);
如何获得我需要的日期?
答案 0 :(得分:4)
您需要一个日期表
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
答案 1 :(得分:2)
这比听起来更复杂,因为你可能有一系列被阻止的日期,并且必须在前一天获得。
如果没有阻止日期或阻止日期在相关日期之前有间隙,这很简单:
driver.find_element_by_id("header_wallet_balance").text
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
获取此类组的第一个日期并在当天减去。
答案 2 :(得分:2)
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语句(如果您没有,那么Zohar Peled会为此提供一个很好的解决方案。您的问题的评论)。
但是,如果您确实有一个日历表或包含日期的表,您可能需要警惕其中的多个条目与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
,它将返回所有包含第19条的4条记录,因为它们都满足此查询。
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;
答案 3 :(得分:0)
感谢所有花时间回应的人。通过结合所有答案,这对我有用。
DECLARE @date = '2016-05-16'
SELECT TOP 1 [Date]
FROM (
SELECT TOP 120
[Date] = dateadd(DAY, -ROW_NUMBER() OVER(ORDER BY c1.name), @date)
FROM [master].[dbo].[spt_values] c1
) D
WHERE D.Date NOT IN (select blockedDate from tbl_BlockedDates)
通过使用否定-ROW_NUMBER()
,我创建了一个日期表,从传递的日期开始逐渐减少。我加入了Tbl_blockedDates
以从表中排除这些日期。
然后我选择了TOP[1]
以获得第一个可用日期。
答案 4 :(得分:0)
你应该能够使用一个简单的递归cte而不需要任何额外的表..
;WITH cte AS (
SELECT DATEADD(DAY, -1, @StartDate) [Start]
UNION ALL
SELECT DATEADD(DAY, -1, [Start])
FROM cte
INNER JOIN @tbl_BlockedDates ON cte.[Start] = blockedDate
)
SELECT MIN([Start]) FROM cte
答案 5 :(得分:0)
CREATE TABLE [dbo].[tbl_BlockedDates](
[BlockedDate] [date] NOT NULL
) ON [PRIMARY]
INSERT INTO [dbo].[tbl_BlockedDates]([BlockedDate]) VALUES ('2016-05-16');
INSERT INTO [dbo].[tbl_BlockedDates]([BlockedDate]) VALUES ('2016-05-15');
INSERT INTO [dbo].[tbl_BlockedDates]([BlockedDate]) VALUES ('2016-05-14');
INSERT INTO [dbo].[tbl_BlockedDates]([BlockedDate]) VALUES ('2016-05-12');
INSERT INTO [dbo].[tbl_BlockedDates]([BlockedDate]) VALUES ('2016-05-11');
Declare @MyDate as Date , @CheckDate as date, @BestDate as Date
Set @MyDate = '2016-05-16';
Set @CheckDate = '2016-05-16';
while (@BestDate is null)
Begin
Set @CheckDate = DateAdd(day,-1,@CheckDate)
If NOT Exists (Select 1 from tbl_BlockedDates where BlockedDate = @CheckDate)
begin
Select @BestDate = @CheckDate
end
END
Select @BestDate as BestDate