[SQL]過濾DateTime欄位資料

本文章分享 DateTime 欄位的 Filter 方式,不在資料欄位上使用Function去Filter。

前陣子看到同事 Apple 寫一個Filter 某一天的SQL,常常會遇到這種查詢條件,所以就記錄下來。

1.準備測試資料

USE tempdb
GO
-- drop table tblDates;
CREATE TABLE tblDates
(
c1 INT,
c2 DATETIME
)
GO

INSERT INTO dbo.tblDates( c1, c2 ) VALUES  (0, '2014-01-06 00:00:00');
INSERT INTO dbo.tblDates( c1, c2 ) VALUES  (1, '2014-01-06 00:00:01');
INSERT INTO dbo.tblDates( c1, c2 ) VALUES  (2, '2014-01-06 01:00:01');
INSERT INTO dbo.tblDates( c1, c2 ) VALUES  (3, '2014-01-06 23:59:59');
INSERT INTO dbo.tblDates( c1, c2 ) VALUES  (4, '2014-01-07 00:00:00');
INSERT INTO dbo.tblDates( c1, c2 ) VALUES  (5, '2014-01-07 11:00:00');
INSERT INTO dbo.tblDates( c1, c2 ) VALUES  (6, '2014-01-07 23:59:59');
INSERT INTO dbo.tblDates( c1, c2 ) VALUES  (7, '2014-01-08 23:59:59');
INSERT INTO dbo.tblDates( c1, c2 ) VALUES  (8, '2014-01-09 00:00:01');
SELECT * FROM dbo.tblDates;

 

2.取得 2014-01-06 的資料,傳入的參數為 2014-01-06 14:12:01

image

 

2.1.取出2014-01-06的開始及結束時間

-- 取得 2014-01-06 的資料
DECLARE @filterDate VARCHAR(32);
-- 有時傳進來的資料,並不會剛好只有日期,例如 GetDate()
SET @filterDate = '2014-01-06 14:12:01';
-- 因為 DateTime,所以比較時,要包含時間進去,所以先取出開始及結束時間
SELECT DATEDIFF(dd,0,@filterDate) AS [到查詢時間的天數]
, DATEADD(dd, DATEDIFF(dd,0,@filterDate), 0) AS [開始時間]
, DATEADD(dd, DATEDIFF(dd,0,CAST(@filterDate AS DATETIME)), 1) AS [LW結束時間];

-- 如果 BETWEEN 要用的話,結束時間要減一秒,如下,
SELECT DATEDIFF(dd,0,@filterDate) AS [到查詢時間的天數]
, DATEADD(dd, DATEDIFF(dd,0,@filterDate), 0) AS [開始時間]
, DATEADD(ss, -1, DATEADD(dd, DATEDIFF(dd,0,CAST(@filterDate AS DATETIME)), 1)) AS [BW結束時間];

image

 

2.2.將開始及結束時間,放到 WHERE 去 Filter

-- 取得 2014-01-06 的資料
DECLARE @filterDate VARCHAR(32);
-- 有時傳進來的資料,並不會剛好只有日期,例如 GetDate()
SET @filterDate = '2014-01-06 14:12:01';
-- 1. >= < + DATEADD
SELECT * FROM dbo.tblDates
WHERE c2 >= DATEADD(dd,  DATEDIFF(dd,0,@filterDate), 0)
AND c2 < DATEADD(dd, DATEDIFF(dd,0,CAST(@filterDate AS DATETIME)), 1);

-- 2. BETWEEN + DATEADD
SELECT * FROM dbo.tblDates
WHERE c2 BETWEEN DATEADD(dd, DATEDIFF(dd,0,@filterDate), 0)
AND DATEADD(ss, -1,  DATEADD(dd, DATEDIFF(dd,0,CAST(@filterDate AS DATETIME)), 1));
-- 因為用BETWEEN 要減 1 秒

image

 

結論

知道如何取出開始及結束時間,及它的使用時機(小於 或是 BETWEEN),即使是開始、結束不同天,也是類似的方式哦!

例如,取得 2014-01-06 ~ 2014-01-08 的資料,將2個時間套進去就可以了,如下,

-- 取得 2014-01-06 ~ 2014-01-08 的資料
DECLARE @startFilterDate VARCHAR(32);
DECLARE @endFilterDate VARCHAR(32);
-- 有時傳進來的資料,並不會剛好只有日期,例如 GetDate()
SET @startFilterDate = '2014-01-06 14:12:01';
SET @endFilterDate = '2014-01-08 23:12:01';

-- 因為 DateTime,所以比較時,要包含時間進去,所以先取出開始及結束時間
SELECT DATEADD(dd, DATEDIFF(dd,0,@startFilterDate), 0) AS [開始時間]
, DATEADD(dd, DATEDIFF(dd,0,CAST(@endFilterDate AS DATETIME)), 1) AS [LW結束時間];

-- 如果 BETWEEN 要用的話,結束時間要減一秒,如下,
SELECT DATEADD(dd, DATEDIFF(dd,0,@startFilterDate), 0) AS [開始時間]
, DATEADD(ss, -1, DATEADD(dd, DATEDIFF(dd,0,CAST(@endFilterDate AS DATETIME)), 1)) AS [BW結束時間];

-- 1. >= < + DATEADD
SELECT * FROM dbo.tblDates
WHERE c2 >= DATEADD(dd, DATEDIFF(dd,0,@startFilterDate), 0)
AND c2 < DATEADD(dd, DATEDIFF(dd,0,CAST(@endFilterDate AS DATETIME)), 1);

-- 2. BETWEEN + DATEADD
SELECT * FROM dbo.tblDates
WHERE c2 BETWEEN DATEADD(dd, DATEDIFF(dd,0,@startFilterDate), 0)
AND DATEADD(ss, -1, DATEADD(dd, DATEDIFF(dd,0,CAST(@endFilterDate AS DATETIME)), 1));
-- 因為用BETWEEN 要減 1 秒

image

Hi, 

亂馬客Blog已移到了 「亂馬客​ : Re:從零開始的軟體開發生活

請大家繼續支持 ^_^