如何获得基于期限最后一天一天,今天的数据

问题描述:

我这里有样本数据:如何获得基于期限最后一天一天,今天的数据

ID Val   dt 
1 Mohan 2017-10-13 13:02:49.493 
2 Manasa 2017-10-12 20:02:49.493 
3 maren 2017-10-13 18:02:49.493 

当我运行今天的声明在下午2点,它应该给结果集6的最后一天PM之后的数据,以及今天的数据,直到今天,当我在今天下午7点运行声明时,它应该在下午6点之后提供当天的数据。

如果我跑了它在今天凌晨2时许,其结果将是这样

ID Val   dt 
1 Mohan 2017-10-13 13:02:49.493 
2 Manasa 2017-10-12 20:02:49.493 

如果我今天跑在下午7点:

ID Val   dt 
3 maren 2017-10-13 18:02:49.493 

基本的东西,如果我跑前下午6点,它应该在下午6点之前给出最后一天的数据,如果我在下午6点之后运行,它应该在下午6点之后给出数据。我已经尝试过DATE DIFF条件但我无法证明结果的正确性 - 任何人都可以请建议吗?

表脚本

Declare @tab table 
(ID INT,Val Varchar(10),dt datetime) 

Insert into @tab (ID,val,dt) 
values (1,'Mohan','2017-10-13 13:02:49.493'), 
(2,'Manasa','2017-10-12 20:02:49.493'), 
(3,'maren','2017-10-13 18:02:49.493') 

尝试这种情况:

DECLARE @Now DATETIME, @FromDate DATETIME 
SET @Now = GETDATE() 
SET @FromDate = DATEADD(HOUR, 18, DATEADD(DAY, DATEDIFF(DAY, 0, @Now) 
    - (CASE WHEN DATEPART(HOUR, @Now) < 18 THEN 1 ELSE 0 END), 0)) 

SELECT @Now, @FromDate 

SELECT * 
FROM @tab 
WHERE @FromDate < dt AND dt <= @Now 

结果:

Now      FromDate 
----------------------- ----------------------- 
2017-10-13 19:36:40.963 2017-10-13 18:00:00.000 

ID   Val  dt 
----------- ---------- ----------------------- 
3   maren  2017-10-13 18:02:49.493 

说明:

@FromDate计算如下:

  • (CASE WHEN DATEPART(HOUR, @Now) < 18 THEN 1 ELSE 0 END) - 如果时间不小于18(下午6点),则返回1
  • DATEADD(HOUR, 18, DATEADD(DAY, DATEDIFF(DAY, 0, @Now) - ... , 0)) - 返回 “6PM日期”,这是依赖于CASE表达式的结果上述
前一天或当天
+0

你能在给定的样本数据实现这个......越来越糊涂 – mohan111

+0

@ mohan111,您可以提供创建表的脚本?你有足够的声誉知道如何问:) – Alex

+0

好的Alex我会修改问题 – mohan111

你可以试试这个:

SELECT * FROM [yourTable] WHERE 
(dt between CONCAT(CAST(GETDATE() AS DATE), ' ', '18:00:00.000') AND 
    CONCAT(CAST(GETDATE() AS DATE), ' ', '23:59:59.999') 
    AND HOUR(GETDATE()) > 18) 
OR 
(dt between CONCAT(CAST(dt AS DATE) - INTERVAL 1 DAY, ' ', '18:00:00.000') 
     AND GETDATE() 
    AND HOUR(GETDATE()) < 18) 
+1

'DATE'和'NOW()'是无效的sql-server函数 – SQLBadPanda

+0

以为你在谈论mysql;) – NullPointer

你可以做到这一点通过创建昨天下午6点,即今天下午6点来模拟你的一天“窗口”,两个日期,根据当前时间是在当前下午6点之前还是之后调整昨天/今天的概念。然后,您只需选择您的数据,其中dt是这两个日期之间(或使用< =和>或任何你需要包含或排除相关行)如...

DECLARE @t table (ID int,Val varchar(30),dt datetime2(3)) 
INSERT @t(ID,Val,dt) 
VALUES(1,'Mohan' ,'2017-10-13T19:02:49.493'), 
     (2,'Manasa','2017-10-12T20:02:49.493'), 
     (3,'maren' ,'2017-10-13T07:02:49.493'); 

DECLARE @now datetime2 = dateadd(HOUR,12,sysdatetime()); 

SELECT *, 
     @now, 
     x.Today6pm, 
     x.Yesterday6pm 
FROM @t AS t 
CROSS APPLY (VALUES(DATEADD(day, DATEDIFF(day,'19000101',cast(@now AS date))-(CASE WHEN cast(@now AS time) < timefromparts(18,00,00,0,0) THEN 1 ELSE 0 END), CAST(timefromparts(18,00,00,0,0) AS DATETIME2(7))), 
        DATEADD(day, DATEDIFF(day,'19000101',cast(@now AS date))+(CASE WHEN cast(@now AS time) > timefromparts(18,00,00,0,0) THEN 1 ELSE 0 END), CAST(timefromparts(18,00,00,0,0) AS DATETIME2(7))))) x(Yesterday6pm,Today6pm) 
WHERE dt BETWEEN x.Yesterday6pm AND x.Today6pm 

这里的CROSS APPLY是simplfy的否则你可以直接将这些函数放在WHERE谓词中。

变量@now仅用于测试以确保调整工作,而不是等到今天晚上6:01分。显然,在你的代码中,只需将@now替换为sysdatetime()即可。

注意:如果您的日期是日期时间,那么一起添加日期和时间“有效”,但它不适用于datetime2。上述方法适用于日期时间和日期时间2,因此更具弹性。

DECLARE @T TABLE 
(
    ID INT, 
    Val VARCHAR(50) ,   
    dt DATETIME 
) 
INSERT INTO @T 
VALUES 
(1, 'Mohan ', '2017-10-13 13:02:49.493'), 
(2, 'Manasa ', '2017-10-12 20:02:49.493'), 
(3, 'maren ', '2017-10-13 18:02:49.493') 

DECLARE @CURRENT datetime = '13 oct 2017 18:00' 
SELECT 
* 
FROM @T 
WHERE 
    (
     CAST(@CURRENT as time) BETWEEN '00:00' AND '18:00' AND 
     dt BETWEEN DATEADD(day,-1,DATEADD(hh,18,CAST(CAST(@CURRENT as date) as datetime))) AND DATEADD(hh,18,CAST(CAST(@CURRENT as date) as datetime)) 
    ) OR 
    (
     CAST(@CURRENT as time) NOT BETWEEN '00:00' AND '18:00' AND 
     dt >=DATEADD(hh,18,CAST(CAST(@CURRENT as date) as datetime)) 
    ) 

您可以试试这个脚本。

SELECT * FROM MyTable WHERE 
((CAST(GETDATE() AS TIME) < '18:00') 
    AND dt < DATEADD(HOUR,18, CAST(CAST(GETDATE() AS DATE) AS DATETIME))) 
OR 
((CAST(GETDATE() AS TIME) >= '18:00') 
    AND dt >= DATEADD(HOUR,18, CAST(CAST(GETDATE() AS DATE) AS DATETIME)))