WHERE DATE_COLUMN = '9999-12-31' 语句导致查询不返回任何结果

Posted

技术标签:

【中文标题】WHERE DATE_COLUMN = \'9999-12-31\' 语句导致查询不返回任何结果【英文标题】:WHERE DATE_COLUMN = '9999-12-31' statements causes query to return no resultsWHERE DATE_COLUMN = '9999-12-31' 语句导致查询不返回任何结果 【发布时间】:2020-02-18 18:00:28 【问题描述】:

我收到的查询从 Access 转换为 SQL Server 时遇到了一个非常奇怪的问题。

查询按预期工作,直到我在 WHERE 子句中添加条件来检查特定日期。

由于 SQL Server 查询需要与链接的 DB2 大型机对话,我不确定日期字段是否兼容。所以为了测试这个以确保正确读取日期,我使用了DATEDIFF()。我还将 select 语句减少到仅出现问题的日期字段,以尝试弄清楚发生了什么,但我仍然没有运气。我已经尝试过任何我能想到的过滤日期的方法。

我尝试了HAVING 子句。

HAVING TERM_DT = '9999-12-31'

我尝试了WHERE 子句。

WHERE TERM_DT = '9999-12-31'

我试图比较JOIN中的日期。

INNER JOIN linked_db2_tbl11 tbl11
    ON tbl11.TERM_DT = '9999-12-31'

我尝试将 CASTCONVERT 字段设置为 DATE 认为日期字段可能不兼容。

CAST(TERM_DT AS DATE) = CAST('9999-12-31' AS DATE)
CONVERT(DATE, TERM_DT) = CONVERT(DATE, '9999-12-31')

在上面的每一个中,我还尝试了TERM_DT >= '9990-12-31',因为没有其他方法起作用,并且由于某种原因,该列有一些拼写错误,例如9998-12-319999-11-31,所以我认为从9990 开始检查应该可以捕获所有内容。仍然没有返回。

我尝试的最后一件事是DATEDIFF()。这也没有用。

DATEDIFF(day, '9990-12-31', TERM_DT) >= 0

除非我将 DATEDIFF() 放在 select 语句中并且不在 WHERE 部分中使用任何内容,否则我会得到我期望的值...

SELECT DATEDIFF(day, '9990-12-31', TERM_DT) AS "DIFF"
,TERM_DT AS "DT"
FROM ...
JOIN ...

返回的数据:

DIFF        DT
-2912352    2017-04-01
-2912261    2017-07-01
-2911852    2018-08-14
-2911852    2018-08-14
-2911624    2019-03-30
-2911624    2019-03-30
-2911532    2019-06-30
-2911532    2019-06-30
3287        9999-12-31
3287        9999-12-31

但是当我在中添加 where 语句时:

SELECT DATEDIFF(day, '9990-12-31', TERM_DT) AS "DIFF"
,TERM_DT AS "DT"
FROM ...
JOIN ...
WHERE DATEDIFF(day, '9990-12-31', TERM_DT) >= 0

我没有得到任何结果:

DIFF        DT

然后我试图翻转与<= 的比较,奇怪的是我得到了所有低于9999-12-31 的值,那么为什么我不能让9999-12-31 的值返回呢?这是一个非常奇怪的情况。

SELECT DATEDIFF(day, '9990-12-31', TERM_DT) AS "DIFF"
,TERM_DT AS "DT"
FROM ...
JOIN ...
WHERE DATEDIFF(day, '9990-12-31', TERM_DT) <= 0

奇怪的是,它应该有这样的效果:

DIFF        DT
-2912352    2017-04-01
-2912261    2017-07-01
-2911852    2018-08-14
-2911852    2018-08-14
-2911624    2019-03-30
-2911624    2019-03-30
-2911532    2019-06-30
-2911532    2019-06-30

所以我可以得到9999-12-31 下面的日期,但不能得到9999-12-31 的日期。 一旦我意识到检查低于9999-12-31 的日期在DATEDIFF() 函数中起作用,我就回去尝试进行原始比较并检查那些较小的日期。成功了……

SELECT DATEDIFF(day, '9990-12-31', TERM_DT) AS "DIFF"
,TERM_DT AS "DT"
FROM ...
JOIN ...
WHERE TERM_DT < '9999-12-31' 

结果:

DIFF        DT
-2912352    2017-04-01
-2912261    2017-07-01
-2911852    2018-08-14
-2911852    2018-08-14
-2911624    2019-03-30
-2911624    2019-03-30
-2911532    2019-06-30
-2911532    2019-06-30

根据上述结果,我没有理由认为WHERE TERM_DT = '9999-12-31' 不会返回:

DIFF        DT
3287        9999-12-31
3287        9999-12-31

但我不明白。我没有得到任何结果。

更新:

我尝试了DATEDIFF(day, '9990-12-31', DH230.DH230_TERM_DT) &lt;&gt; 0 @Ziad Mehmood 提到的,奇怪的是我得到了所有的负值,但没有一个正值。

DIFF        DT
-2912352    2017-04-01
-2912261    2017-07-01
-2911852    2018-08-14
-2911852    2018-08-14
-2911624    2019-03-30
-2911624    2019-03-30
-2911532    2019-06-30
-2911532    2019-06-30

第二次更新:

当我将 WHERE 语句移至 SELECT 中的 CASE 时,它显然有效。比较是正确的。但在 WHERE 部分不起作用。

SELECT DATEDIFF(day, '9990-12-31', TERM_DT) AS "DIFF"
,TERM_DT AS "DT"
,CASE WHEN DH230.DH230_TERM_DT >'2100-12-31' THEN 'True' else 'False' end
FROM ...
JOIN ...

结果:

DIFF        DT  (No column name)
-2911624    2019-03-30  False
-2911532    2019-06-30  False
-2912261    2017-07-01  False
-2912352    2017-04-01  False
3287        9999-12-31  True
3287        9999-12-31  True
-2911624    2019-03-30  False
-2911532    2019-06-30  False
-2911852    2018-08-14  False
-2911852    2018-08-14  False

因此,我又在 WHERE 子句中运行了 CASE 语句。

SELECT DATEDIFF(day, '9990-12-31', TERM_DT) AS "DIFF"
,TERM_DT AS "DT"
FROM ...
JOIN ...
WHERE CASE WHEN DH230.DH230_TERM_DT >'2100-12-31' THEN 'True' else 'False' end = 'True'

但没有结果:

DIFF        DT

现在又变得奇怪了:

WHERE CASE WHEN DH230.DH230_TERM_DT >'2100-12-31' THEN 'True' else 'False' end = 'False'

返回:

DIFF        DT
-2912352    2017-04-01
-2912261    2017-07-01
-2911624    2019-03-30
-2911532    2019-06-30
-2911624    2019-03-30
-2911532    2019-06-30
-2911852    2018-08-14
-2911852    2018-08-14

太奇怪了!

SQL Server 和链接的 DB2 大型机之间是否存在可能导致此问题的问题?

这样的事情发生有什么已知的原因吗?

我确实从一个 select 语句创建了一个本地 SQL Server 表来检查字段的数据类型。

该字段是根据 SSMS 的 DATE 数据类型。

作为参考,我在下面添加了完整的查询,并进行了一些混淆。可能是关于 JOIN 的某些问题导致了问题。

SELECT DATEDIFF(day, '9990-12-31', linked_db2_tbl11.linked_db2_tbl11_TERM_DT) AS "DIFF"
,linked_db2_tbl11.linked_db2_tbl11_TERM_DT AS "DT"

FROM local_database.dbo.local_table1 IR 
RIGHT JOIN linked_db2_tbl1
INNER JOIN linked_db2_tbl2
INNER JOIN linked_db2_tbl3
INNER JOIN linked_db2_tbl4
INNER JOIN linked_db2_tbl5
INNER JOIN linked_db2_tbl6
INNER JOIN linked_db2_tbl7
INNER JOIN linked_db2_tbl8
INNER JOIN linked_db2_tbl9 
ON linked_db2_tbl8.linked_db2_tbl8_SUB_SVC_TYP = linked_db2_tbl9.linked_db2_tbl9_SUB_SVC_TYP
INNER JOIN linked_db2_tbl10 
ON linked_db2_tbl9.linked_db2_tbl9_PACKAGE_ID = linked_db2_tbl10.linked_db2_tbl10_PACKAGE_ID 
ON linked_db2_tbl7.linked_db2_tbl7_PACKAGE_ID = linked_db2_tbl10.linked_db2_tbl10_PACKAGE_ID
INNER JOIN linked_db2_tbl11
ON linked_db2_tbl9.linked_db2_tbl9_SVC_TYP = linked_db2_tbl11.linked_db2_tbl11_SVC_TYP
AND linked_db2_tbl9.linked_db2_tbl9_PACKAGE_ID = linked_db2_tbl11.linked_db2_tbl11_PACKAGE_ID 
ON linked_db2_tbl6.linked_db2_tbl6_COMP_ID = linked_db2_tbl7.linked_db2_tbl7_COMP_ID 
AND linked_db2_tbl6.linked_db2_tbl6_COMP_ID = linked_db2_tbl11.linked_db2_tbl11_COMP_ID 
ON linked_db2_tbl5.linked_db2_tbl5_COMP_ID = linked_db2_tbl6.linked_db2_tbl6_COMP_ID 
ON linked_db2_tbl4.linked_db2_tbl4_ELEMENT_ID = linked_db2_tbl5.linked_db2_tbl5_ELEMENT_ID 
AND linked_db2_tbl4.linked_db2_tbl4_ELEMENT_ID = linked_db2_tbl11.linked_db2_tbl11_ELEMENT_ID 
ON linked_db2_tbl3.linked_db2_tbl3_ELEMENT_ID = linked_db2_tbl4.linked_db2_tbl4_ELEMENT_ID 
AND linked_db2_tbl3.linked_db2_tbl3_CHG_CD = linked_db2_tbl11.linked_db2_tbl11_CHG_CD 
ON linked_db2_tbl2.linked_db2_tbl2_CHG_CD = linked_db2_tbl3.linked_db2_tbl3_CHG_CD 
ON linked_db2_tbl1.linked_db2_tbl1_SUB_SVC_TYP = linked_db2_tbl8.linked_db2_tbl8_SUB_SVC_TYP 
AND linked_db2_tbl1.linked_db2_tbl1_HWIR_SVC_TYP = linked_db2_tbl8.linked_db2_tbl8_HWIR_SVC_TYP 
AND linked_db2_tbl1.linked_db2_tbl1_SVC_ID = linked_db2_tbl11.linked_db2_tbl11_LEVEL_ID
INNER JOIN linked_db2_tbl12
INNER JOIN linked_db2_tbl13 
ON linked_db2_tbl12.linked_db2_tbl12_RATE_PLAN = linked_db2_tbl13.linked_db2_tbl13_RATE_PLAN 
ON linked_db2_tbl1.linked_db2_tbl1_SVC_ID = linked_db2_tbl13.linked_db2_tbl13_SVC_ID
INNER JOIN linked_db2_tbl14 
ON linked_db2_tbl1.linked_db2_tbl1_UPPER_ID = linked_db2_tbl14.linked_db2_tbl14_CORP_ID 
ON IR.CHG_CD = linked_db2_tbl11.linked_db2_tbl11_CHG_CD 
LEFT JOIN linked_db2_tbl15 
ON linked_db2_tbl14.linked_db2_tbl14_CORP_ID = linked_db2_tbl15.linked_db2_tbl15_INT_ID
INNER JOIN linked_db2_tbl18
ON linked_db2_tbl1.linked_db2_tbl1_CNTL_LOCN_ID = linked_db2_tbl18.linked_db2_tbl18_COMS_LOCN_ID
JOIN local_database.dbo.local_table2 OT
ON linked_db2_tbl14.linked_db2_tbl14_CORP_ID = OT.CORP_ID
WHERE OT.USER_ID = 'SOMEID'
AND DATEDIFF(day, '9990-12-31', linked_db2_tbl11.linked_db2_tbl11_TERM_DT) >= 0

【问题讨论】:

"可能是 JOIN 或 group by 的某些原因导致了问题。"您是否尝试过简化为只涉及包含此日期字段的表的更简单的 SQL 语句? “由于 SQL Server 查询需要与链接的 DB2 大型机对话。”这是否意味着实际数据根本不在 SQL Server 中?我想这可能是一个重要的观点。 (但这意味着我无法提供帮助。) @DaveCosta 是的,我有。如果我只碰那个表,日期比较就可以了。 @DaveCosta 的一些数据是 SQL Server。准确地说是2张桌子。其余的在链接服务器上。 【参考方案1】:

为什么不直接使用这样的东西呢?

where term_dt > '2100-01-01'

如果你在那么远的将来有真正的约会,我会感到惊讶。

此外,您对 date_diff() 的论点倒数,这就是数字为负数的原因。

【讨论】:

where term_dt &gt; '2100-01-01' 不返回任何数据。和DATEDIFF() 我尝试了DATEDIFF(day, '9990-12-31', TERM_DT)DATEDIFF(day, TERM_DT, '9990-12-31') 奇怪的是where term_dt &lt; '2100-01-01' 确实返回了数据...【参考方案2】:

复制

Create Table [DateTest] (
    [date] date NOT NULL
)

insert into [dateTest] ([date])
values 
('2017-04-01'),
('2017-07-01'),
('2018-08-14'),
('2018-08-14'),
('2019-03-30'),
('2019-03-30'),
('2019-06-30'),
('2019-06-30'),
('9999-12-31'),
('9999-12-31')

SELECT DATEDIFF(day, '9990-12-31', dt.[Date]) AS "DIFF"
,dt.[Date] as [DT]
FROM [dateTest] as DT

诊断

复制您的声明(引用)时,我运行了以下内容:

“但是当我在中添加 where 语句时:”

SELECT DATEDIFF(day, '9990-12-31', dt.[Date]) AS "DIFF"
,dt.[Date] as [DT]
FROM [dateTest] as DT
WHERE DATEDIFF(day, '9990-12-31', dt.[Date]) >= 0

我得到了预期的回报:

DIFF    DT
3287    9999-12-31
3287    9999-12-31

您的 SQL 语法正确,但可能存在数据类型问题。能否提供更多关于查询表的信息?


索取更多信息

表定义的简单案例是理想的,或者只是您要连接的 2 个表和数据类型的简单行示例。

如果不知道访问文件的确切定义,就很难复制您的问题。引用脚本中的表太多,无法在没有直接克隆的情况下进行隔离。通过创建一个简化的示例,您或许能够解决您的问题。


推荐

如果这是从基于 Access 的数据库的一次性转换,您可以查看 SSMS (Sql Server Management Studio) 以使用直接导入访问数据库。

如果您正在寻找一种方法来安排从已知的 Access 文件中检索,那么使用 Access 文件而不是直接写入 SQL 数据库的业务需求是什么?您的问题可能有更简单的解决方案。

【讨论】:

通过创建一个简化的示例,您也许可以解决您的问题...我试过了。我从包含日期字段的表中做了一个简单的选择,并且该字段接受了我的 where 语句就好了。我复制了 SQL 查询并手动重写它以在 SSMS 中工作。该查询在没有 WHERE 子句的情况下工作得很好,但只有在我添加日期条件时才会失败。也就是说,您的情况仅在 SSMS 内有效。带有日期字段的表位于 DB2 链接服务器中。 我确实做了一个select linked_db2_tbl11_TERM_DT into LOCAL_TABLE from linked_db2_tbl11,然后在SSMS的设计视图中检查了数据类型,它是“日期”的数据类型。 我没有 DB2 定义的上下文,也没有表的定义。尝试将您的连接简化为集群的较小连接。这将有助于您的诊断。就个人而言,我是“With”子句样式的忠实粉丝,因为它可以更轻松地诊断子查询问题。您能否为要连接的表提供一个简单的 3 表定义以及一些数据示例?我猜这可能是别名问题,或语法问题,而不是后勤问题。查看长查询,您的 select 语句中存在语法问题,并且您的一些连接(缺少逗号)。 这个问题也与Access无关,我接受了一个正在访问的查询并在SSMS中重写了它。本地表在 SQL Server 中,其他表是链接的 DB2 大型机。所以此时不​​涉及任何访问。 没有缺少逗号。由于混淆原因,我的示例中缺少一个。该查询在没有 WITH 语句的情况下提取所有预期数据,因此我知道该查询是有效的。我想我唯一的选择是尝试越来越少的加入,直到它起作用。【参考方案3】:

请根据数据尝试类似的操作

SELECT DATEDIFF(day, '9990-12-31', TERM_DT) AS "DIFF"
,TERM_DT AS "DT"
FROM ...
JOIN ...
WHERE DATEDIFF(day, '2100-01-01', TERM_DT) <> 0
GROUP BY ...

希望这会有所帮助。

【讨论】:

&lt;&gt; 0 会得到所有结果,因为我认为我没有写在 WHERE 语句中。即使它有效,也不会是正确的结果。 奇怪的是 DATEDIFF(day, '9990-12-31',DH230.DH230_TERM_DT) &lt;&gt; 0 返回与 DATEDIFF(day, '9990-12-31',DH230.DH230_TERM_DT) &lt; 0 相同的数据,但不返回任何 &gt; 0。至少这告诉了我一些事情。没有解决问题,但出于某种原因告诉我 > 值由于某种奇怪的原因被忽略了。

以上是关于WHERE DATE_COLUMN = '9999-12-31' 语句导致查询不返回任何结果的主要内容,如果未能解决你的问题,请参考以下文章

统计出当前各个title类型对应的员工当前(to_date='9999-01-01')薪水对应的平均工资。结果给出title以及平均工资avg

SQL 创建唯一 id WHERE 不在两个表中

创建年份为 9999 的事实表

为啥在 Python 中 Decimal('0') > 9999.0 为真?

12c 中的 Oracle 日期格式 9999-06-15T00:00:00.000+0000

在 DB2 中选择期间 SQLCODE= -9999