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'
我尝试将 CAST
和 CONVERT
字段设置为 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-31
和9999-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) <> 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 > '2100-01-01'
不返回任何数据。和DATEDIFF()
我尝试了DATEDIFF(day, '9990-12-31', TERM_DT)
和DATEDIFF(day, TERM_DT, '9990-12-31')
。
奇怪的是where term_dt < '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 ...
希望这会有所帮助。
【讨论】:
<> 0
会得到所有结果,因为我认为我没有写在 WHERE 语句中。即使它有效,也不会是正确的结果。
奇怪的是 DATEDIFF(day, '9990-12-31',DH230.DH230_TERM_DT) <> 0
返回与 DATEDIFF(day, '9990-12-31',DH230.DH230_TERM_DT) < 0
相同的数据,但不返回任何 > 0
。至少这告诉了我一些事情。没有解决问题,但出于某种原因告诉我 > 值由于某种奇怪的原因被忽略了。以上是关于WHERE DATE_COLUMN = '9999-12-31' 语句导致查询不返回任何结果的主要内容,如果未能解决你的问题,请参考以下文章
统计出当前各个title类型对应的员工当前(to_date='9999-01-01')薪水对应的平均工资。结果给出title以及平均工资avg
为啥在 Python 中 Decimal('0') > 9999.0 为真?