我有几个表,通常具有可为空的“CreatedDate”和/或“ModifiedDate”日期时间列。我想要一个查询,可以从任何单个表中进行选择,其中一个、两个或都不存在日期时间列,并且每列都BETWEEN
提供(单独的)范围。
这是一个粗略的(非工作的)示例。这尝试用来COL_LENGTH
确定列是否存在。但是,如果一列不存在,则会引发错误,我相信是因为WHERE
仍在评估整个列。
SELECT * FROM tableName
WHERE 1=1 AND
(COL_LENGTH(tableName, 'CreatedDate') IS NULL OR CreatedDate BETWEEN @CreatedFrom AND @CreatedTo) AND
(COL_LENGTH(tableName, 'ModifiedDate') IS NULL OR ModifiedDate BETWEEN @ModifiedFrom AND @ModifiedTo)
这可以通过动态 SQL 来解决。但是,在这种情况下,我仅限于以读取为中心的权限。所以没有 EXEC、CREATE 或 INSERT。
这可以用静态 SQL 实现吗?
示例表
两列:
DECLARE @Table1 table
(
Id int NOT NULL,
CreatedDate datetime NULL,
ModifiedDate datetime NULL
);
INSERT @Table1
(Id, CreatedDate, ModifiedDate)
VALUES
(1, NULL, NULL),
(2, NULL, '20230101 01:23:45.678'),
(3, '20230101 02:34:56.789', NULL),
(4, '20230101 03:45:00.891', '20230101 04:56:00.789');
DECLARE
@CreatedFrom datetime = {TS '2023-01-01 01:30:00.000'},
@CreatedTo datetime = {TS '2023-12-31 23:30:00.000'},
@ModifiedFrom datetime = {TS '2023-01-01 06:00:00.000'},
@ModifiedTo datetime = {TS '2023-12-31 18:00:00.000'};
用一列:
DECLARE @Table2 table
(
Id int NOT NULL,
CreatedDate datetime NULL
);
INSERT @Table2
(Id, CreatedDate)
VALUES
(1, NULL),
(2, '20230101 02:34:56.789');
DECLARE
@CreatedFrom datetime = {TS '2023-01-01 01:30:00.000'},
@CreatedTo datetime = {TS '2023-12-31 23:30:00.000'};
感谢@PaulWhite 提供的最初示例。
是的,这个棘手的问题可以用简单的 SQL 来解决,方法是相当晦涩难懂。
有关更详细的解释和最初的想法,请参阅 Andriy M 和我在两个类似问题中的答案:
为什么我不能使用 case 语句来查看列是否存在而不是从中进行选择?
如果列存在,如何选择特定行;如果列不存在,如何选择所有行
在你的情况下 - 以及假设
这会起作用:
可以使用 XML 来实现此目的: