sql-server - 在 nvarchar 列上使用 between 子句查找范围不起作用
问题描述
我有 3 个 nvarchar 列 user_3、user_4 和描述。我正在设置是和否标志。如果描述列中的值相等或介于 user_3 和 User4 之间,则将标志设置为“N”,否则将标志设置为“Y”。
这是我到目前为止编写的 SQL 脚本。它在某些情况下有效,但并非总是如此。查看带有结果的图像。例如,它在第 1 行有效,但在第 6 行无效。我究竟做错了什么?
SELECT [B].USER_3,[B].USER_4,A.DESCRIPTION,
(case when Isnumeric(A.DESCRIPTION) <> 1 then 'Y'
else case when (CASE WHEN Isnumeric(A.DESCRIPTION) = 1 then
cast(A.DESCRIPTION AS decimal(10,5)) else 0 end)
between ( CASE WHEN Isnumeric([B].USER_4) = 1 then
cast([B].USER_4 AS decimal(10,5)) else 0 end) and
(CASE WHEN Isnumeric([B].USER_3) = 1 then cast([B].USER_3 AS decimal(10,5)) else 0 end)
then 'N' else 'Y' end end) as Flagset
from A , B
这是结果的屏幕截图
解决方案
问题在于您BETWEEN
按照文档使用:
如果 test_expression 的值大于或等于 begin_expression 的值且小于或等于 end_expression 的值,则 BETWEEN 返回 TRUE。
因为不知道是上限USER_3
还是USER_4
下限,所以需要双向测试。
注意:对于这种查询,我更喜欢预先计算CROSS APPLY
我需要的所有值(在这种情况下使用)。它使跟踪和调试变得更加容易。
SELECT USER_3, USER_4, [DESCRIPTION]
, CASE WHEN ISNUMERIC([DESCRIPTION]) <> 1 THEN 'Y' ELSE
CASE WHEN CASE WHEN ISNUMERIC([DESCRIPTION]) = 1 THEN CAST([DESCRIPTION] AS decimal(10,5)) ELSE 0 END BETWEEN CASE WHEN ISNUMERIC(USER_4) = 1 THEN CAST(USER_4 AS decimal(10,5)) ELSE 0 END AND
CASE WHEN ISNUMERIC(USER_3) = 1 THEN CAST(USER_3 AS decimal(10,5)) ELSE 0 END
THEN 'N' ELSE 'Y' END END AS Flagset
, CASE WHEN DNUMERIC <> 1 THEN 'Y' ELSE CASE WHEN DESCRIPTIOND BETWEEN USER_4D AND USER_3D OR DESCRIPTIOND BETWEEN USER_3D AND USER_4D THEN 'N' ELSE 'Y' END END CorrectedFlagSet
FROM (VALUES
('1.395','1.385','1.390')
, ('22.025','41.425','22')
, ('22.025','41.425','23.025')
) AS X (USER_3, USER_4, [DESCRIPTION])
CROSS APPLY (VALUES (
CASE WHEN ISNUMERIC(USER_3) = 1 THEN CAST(USER_3 AS decimal(10,5)) ELSE 0 END
, CASE WHEN ISNUMERIC(USER_4) = 1 THEN CAST(USER_4 AS decimal(10,5)) ELSE 0 END
, CASE WHEN ISNUMERIC([DESCRIPTION]) = 1 THEN CAST([DESCRIPTION] AS decimal(10,5)) ELSE 0 END
, CASE WHEN ISNUMERIC([DESCRIPTION]) = 1 THEN 1 ELSE 0 END
)) AS Y (USER_3D, USER_4D, DESCRIPTIOND, DNUMERIC);
回报:
USER_3 | USER_4 | 描述 | 标志集 | 更正标志集 |
---|---|---|---|---|
1.395 | 1.385 | 1.390 | ñ | ñ |
22.025 | 41.425 | 22 | 是 | 是 |
22.025 | 41.425 | 23.025 | 是 | ñ |
我敢肯定,我不必提及您确实应该首先以数字形式存储这些数据,因为它会表现得更好并为您节省很多未来的问题。
布局合理且大小写一致的查询也有助于理解和调试它们。
最后提供一个包含示例数据、您的查询和所需结果的最小可重复示例,如此处所示,使人们更容易提供帮助。
推荐阅读
- javascript - 使用 jQuery UI 将特定日期变灰不起作用
- reactjs - 缩放和平移画布的反应包
- javascript - ckeditor5 从内容中删除视频标签
- c++ - ubuntu 中 C++ 的 Notepad++ NppExec 脚本
- python - Groupby 并删除 NaN 行,同时在 Pandas 中保留一个
- linux - 使用脚本检查 netcat 反向 shell
- c# - 将图表数据绑定到日期选择器以显示自定义时间线
- python - 访问类 python 之外的文件
- python - 我可以创建一个函数来报告 Python 中的输出列表吗?
- amazon-cloudwatch - 根据标签过滤 EC2,同时使用 Cloudwatch 事件规则通过 SNS 发送 EC2 实例状态更改通知