【发布时间】: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张桌子。其余的在链接服务器上。
标签: sql sql-server date db2 where-clause