编辑:我意识到我试图编辑的字段是nvarchar(max),并且包含大量的垃圾数据,并且我试图使用的扩展都是单一的角色,因为逗号分隔的values...it不太可能完成我所请求的操作。非常感谢所有帮助过我们的人!
在我问之前,要知道我对数据库有只读访问权限,不能写入临时tables...as,这是我想过的一个解决方案……
我目前正在使用以下查询:
USE Database
GO
DECLARE @dn VARCHAR(13)
SET @dn = '%15555555555%'
SELECT switch_extension, line_number, system_configurations.name, system_configurations.description, lines.system_id
FROM lines, system_configurations
WHERE lines.system_id=system_configurations.system_id
AND switch_extension like @dn
AND lines.status = 1
SELECT distinct CS.name, CTD.cti_data_value
FROM cti_source AS CS with (nolock)
JOIN cti_source_data AS CTD with (nolock)ON CS.cti_source_id = CTD.cti_source_id
--WHERE CS.status = 1
AND (CTD.cti_data_name = 'Agent_Ext'or CTD.cti_data_name = 'IVR_Ext')
AND CTD.cti_data_value LIKE @dn问题是,CTD.cti_data_value可以包含以字符串形式存储的范围,而不是具有单个值的新行,例如'15551112222-15551113333‘,而不是15551112222,15551112223,...
如果我查询这个范围内的@dn (除非是该范围的开始或结束),则不会得到任何结果(在上面的示例中,如果我搜索15551112345,则不会有任何结果,即使它存在于“范围”中)。
有没有办法改变这一点,在这个单独的字符串中得到min/max,然后找到min/max之间的结果,或者我是不是遇到了麻烦?
发布于 2017-02-22 01:33:38
您需要将CTD.cti_data_value中的值拆分为范围的下限和上限。更改where子句中的此行...
AND CTD.cti_data_value LIKE @dn对这个..。
AND @dn BETWEEN
CASE WHEN CHARINDEX('-', CTD.cti_data_value) > 0 THEN
SUBSTRING(CTD.cti_data_value, 1, CHARINDEX('-', CTD.cti_data_value) - 1)
ELSE
CTD.cti_data_value
END
AND
CASE WHEN CHARINDEX('-', CTD.cti_data_value) > 0 THEN
SUBSTRING(CTD.cti_data_value, CHARINDEX('-', CTD.cti_data_value) + 1, LEN(CTD.cti_data_value) - CHARINDEX('-', CTD.cti_data_value))
ELSE
CTD.cti_data_value
END这将适应具有一系列值(例如X-Y)或仅具有单一值的情况。我必须警告您,比较字符串变量(例如CHAR、VARCHAR等)中的数值。可能导致不可预知的结果。例如,当比较字符串变量中的数值时,"2“大于"10”。
如果您绝对确定CTD.cti_data_value中的数字将始终是相同的位数,那么您就可以了。如果不是这样,您应该将数值转换为INT (或适合您的情况的任何值),如下所示...
AND CONVERT(INT, @dn) BETWEEN
CONVERT(INT, CASE WHEN CHARINDEX('-', CTD.cti_data_value) > 0 THEN
SUBSTRING(CTD.cti_data_value, 1, CHARINDEX('-', CTD.cti_data_value) - 1)
ELSE
CTD.cti_data_value
END)
AND
CONVERT(INT, CASE WHEN CHARINDEX('-', CTD.cti_data_value) > 0 THEN
SUBSTRING(CTD.cti_data_value, CHARINDEX('-', CTD.cti_data_value) + 1, LEN(CTD.cti_data_value) - CHARINDEX('-', CTD.cti_data_value))
ELSE
CTD.cti_data_value
END)发布于 2017-02-22 01:37:39
我认为您需要将字符串拆分成不同的组件。请参阅Splitting the string in sql server
现在这是一个读/写版本,但您正在做类似的事情。然后,最小值将始终是分隔符之前的位,而最大值将始终是分隔符之后的位。
第二种选择是用.net编写一个用户定义的函数,该函数接受字符串,执行健全性检查,并返回您要查找的相应值。如果性能很关键,那么使用CLR在这里实际上可能是一件好事。
但在没有CLR的情况下,您需要:
发布于 2017-02-22 01:46:32
您可以使用CTE而不是表格,通过拆分范围并检查@dn是否在这些值之间来计算范围中的最小值和最大值。确保@dn声明为BIGINT。我假设你的值总是BIGINT (你的值超过INT)。
这里有一个有效的例子来证明这一点:
DECLARE @dn BIGINT = 15555555555;
--SET @dn = 15551112223;
WITH cti_source_data AS (
SELECT *
FROM (VALUES ('15555555555'), ('15551112222-15551113333')) AS V (cti_data_value)
), CTD AS (
SELECT *,
CASE CHARINDEX('-', cti_data_value) WHEN 0 THEN cti_data_value ELSE SUBSTRING(cti_data_value, 0, CHARINDEX('-', cti_data_value)) END MinValue,
SUBSTRING(cti_data_value, CHARINDEX('-', cti_data_value)+1, LEN(cti_data_value)) MaxValue
FROM cti_source_data
)
SELECT *
FROM CTD
WHERE @dn BETWEEN MinValue AND MaxValue对于您的查询,您需要用计算以下最小值和最大值的CTE替换这些表:
DECLARE @dn BIGINT = 15555555555;
SELECT switch_extension, line_number, system_configurations.name, system_configurations.description, lines.system_id
FROM lines, system_configurations
WHERE lines.system_id=system_configurations.system_id
AND switch_extension like '%' + @dn '%'
AND lines.status = 1
;WITH CTD AS (
SELECT *,
CASE CHARINDEX('-', cti_data_value) WHEN 0 THEN cti_data_value ELSE SUBSTRING(cti_data_value, 0, CHARINDEX('-', cti_data_value)) END MinValue,
SUBSTRING(cti_data_value, CHARINDEX('-', cti_data_value)+1, LEN(cti_data_value)) MaxValue
FROM cti_source_data (NOLOCK)
)
SELECT distinct CS.name, CTD.cti_data_value
FROM cti_source AS CS with (nolock)
JOIN ON CS.cti_source_id = CTD.cti_source_id
--WHERE CS.status = 1
AND (CTD.cti_data_name = 'Agent_Ext'or CTD.cti_data_name = 'IVR_Ext')
--AND CTD.cti_data_value LIKE @dn
AND @dn BETWEEN CTD.MinValue AND CTD.MaxValuehttps://stackoverflow.com/questions/42373472
复制相似问题