2016-12-07 43 views
0

我正在嘗試創建一個存儲過程。 在where子句中比較三個日期值的最有效方法是什麼?tsql最有效的方法來比較where子句中的三個日期值?

例子:

tbl1.Date1, 
tbl2.Date2, -- NOTE: Date2 can be NULL. 
tbl3.Date3 

示例數據:

Date1   Date2   Date3 
2016-12-20  2016-11-21  2016-11-30 
2016-11-21  NULL   2016-12-20 

首先,我比較日期1和date2,我選擇 「做大」 的日期。 然後我比較這個「更大」的日期到Date3。 如果比較成立,我將值寫入表中。

-- This is simplified example: 
INSERT INTO records 
(
    [user_date], 
    [user_name] 
) 
SELECT 
    tbl1.Date1, 
    tbl1.user_name 
FROM 
    table1 AS tbl1 
    INNER JOIN table2 AS tbl2 ON tbl1.id = tbl2.id 
    INNER JOIN table3 AS tbl3 ON tbl2.id = tbl3.id 
WHERE 
    -- I need to know what is bigger, Date1 or Date2, so I can compare correct date to Date3. 
    ISNULL(tbl2.Date2, tbl1.Date1) <= tbl3.Date3 -- ISNULL, doesn't work here, because Date2 and Date1 can get a value and comparison fails if Date1 is bigger than Date3. 
    AND ISNULL(tbl2.Date2, tbl1.Date1) > tbl3.last_date 

回答

0

可以使用case expression,或inline if,有條件地返回兩個日期的做大,進行比較。

示例數據

-- Sample data. 
DECLARE @Sample TABLE 
    (
     Date1 DATE NOT NULL, 
     Date2 DATE NULL, 
     Date3 DATE NOT NULL 
    ) 
; 

INSERT INTO @Sample 
    (
     Date1, 
     Date2, 
     Date3 
    ) 
VALUES 
    ('2016-01-02', NULL,   '2016-01-01'), -- D1 > D3. 
    ('2015-12-31', '2016-01-02', '2016-01-01'), -- D2 > D1 and D3 
    ('2015-12-30', '2016-12-31', '2016-01-01') -- D3 > D1 and D2 
; 

案例表達

-- Using a CASE EXPRESSION. 
SELECT 
    CASE WHEN s.Date2 > s.Date1 THEN s.Date2 ELSE s.Date1 END AS Bigger_of_D1_D2, 
    * 
FROM 
    @Sample AS s       
WHERE 
    CASE WHEN s.Date2 > s.Date1 THEN s.Date2 ELSE s.Date1 END > s.Date3 
; 

內嵌如果(SQL塞雷爾語2012,或以上)

-- Using an INLINE IF. 
SELECT 
    IIF(s.Date2 > s.Date1, s.Date2, s.Date1) AS Bigger_of_D1_D2, 
    * 
FROM 
    @Sample AS s       
WHERE 
    IIF(s.Date2 > s.Date1, s.Date2, s.Date1) > s.Date3 
;  

這兩種方法都依賴於NULL與任何事物都不相等的事實。這意味着如果Date2爲空,檢查D2對D1將始終返回false。如果Date1也允許NULL,這種技術會失敗。在這種情況下,您可以擴展case表達式以在更多的表達式中包含或包含ISNULL函數。

第二個選項是sytactic sugar的示例。在幕後,SQL Server會根據MSDN將代碼轉換爲簡單的表達式:

IIF是編寫CASE表達式的簡寫方式。

+0

在我的情況IIF是最好的解決方法=)謝謝! – 3volution

1

也許是這樣的?

Declare @tbl1 table (id int,date1 date);Insert Into @tbl1 values (1,'2016-12-20'),(2,'2016-11-21 '); 
Declare @tbl2 table (id int,date2 date);Insert Into @tbl2 values (1,'2016-11-21'),(2,null); 
Declare @tbl3 table (id int,date3 date);Insert Into @tbl3 values (1,'2016-12-30'),(2,'2016-12-20'); 


Select User_Date = (Select max(d) from (values(date1),(date2),(date3)) D(D)) 
     ,A.ID 
From @tbl1 A 
Join @tbl2 B on A.ID=B.ID 
Join @tbl3 C on A.ID=C.ID 

返回

User_Date ID 
2016-12-30 1 
2016-12-20 2 
0

這裏是我的建議:

INSERT INTO records 
(
    [user_date], 
    [user_name] 
) 
SELECT tbl1.Date1 
     ,tbl1.user_name 
FROM table1 as tbl1 
INNER JOIN table2 as tbl2 on tbl1.ID=tbl2.ID 
INNER JOIN table3 as tbl3 on tbl1.ID=tbl3.ID 
WHERE (SELECT CASE WHEN tbl1.Date1 > ISNULL(tbl2.Date2,'1900-01-01') THEN tbl1.Date1 ELSE tbl2.Date2 END) <= tbl3.Date3 
     AND 
     (SELECT CASE WHEN tbl1.Date1 > ISNULL(tbl2.Date2,'1900-01-01') THEN tbl1.Date1 ELSE tbl2.Date2 END) > tbl3.last_date 
相關問題