我正在尝试创建一个存储过程。 在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
首先,我比较Date1和Date2,我选择"更大"日期。 然后我比较这个"更大"日期到日期3。 如果comparsion为true,我会将值写入table。
-- 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 :(得分: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
答案 1 :(得分: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
;
内联If(SQL Serer 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为null,则对D1检查D2将始终返回false。如果Date1也允许NULL,则此技术将失败。在这种情况下,您可以扩展case表达式以包含更多表达式,或包含ISNULL函数。
第二个选项是sytactic sugar的示例。在幕后,根据MSDN:
,SQL Server会将您的代码转换为简单的大小写表达式IIF是编写CASE表达式的简便方法。
答案 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