我的数据库表如下所示:
ID Value
-------------
1 a1¦aa¦a2
1 b1¦aa¦b2
1 b3¦tt¦b3
2 a2¦aa¦z1
2 b2¦tt¦z2
2 b3¦tt¦z3
我正在尝试将每个值拆分为|作为断点起作用:
Select
SUBSTRING(MT.Value, 1, CHARINDEX ( '¦' ,MT.Value) - 1) [part1],
SUBSTRING(MT.Value, CHARINDEX ( '¦' ,MT.Value) + 1, 2) [part2],
RIGHT(MT.Value,CHARINDEX('¦',REVERSE(MT.Value),0)-1) [part3]
from
mytable MT
where
MT.id = 1
但是后来我尝试包含一个连接来匹配id2到id1的记录,其中第三部分匹配,SQL Server抛出错误:
传递给LEFT或SUBSTRING函数的长度参数无效。
代码:
Select
SUBSTRING(MT.Value, 1, CHARINDEX ( '¦' ,MT.Value) - 1) [part1],
SUBSTRING(MT.Value, CHARINDEX ( '¦' ,MT.Value) + 1, 2) [part2],
RIGHT(MT.Value, CHARINDEX('¦', REVERSE(MT.Value), 0) - 1) [part3],
mt1.value
Join
mytable mt1 on mt1.ID = 2
and RIGHT(mt.Value, CHARINDEX('¦', REVERSE(mt.Value), 0) - 1) = SUBSTRING(mt1.Value, 1, CHARINDEX ( '¦' , mt1.Value) - 1)
where
MT.id = 1
from
mytable MT
有没有人知道我还能做什么,或者我哪里出错?
答案 0 :(得分:1)
您正在“值”列中为“|”执行CHARINDEX,然后减去1.这很可能意味着至少有一条记录,其中字符串中不存在“|”。所以你的CHARINDEX将=零(0)然后你减去1是一个负数。您不能在子字符串或左侧函数中使用负数。
一个解决方案就是填写你的陈述:
[Part1] =
CASE
WHEN CHARINDEX ( '¦' ,MT.Value) = 0 THEN MT.Value
ELSE SUBSTRING(MT.Value, 1, CHARINDEX ( '¦' ,MT.Value)-1)
END
答案 1 :(得分:0)
因为你有一个工作的select语句,为什么不把它包装在common table expression (CTE)中。现在您可以重用已返回的列。
为了让每个人都能更轻松地分享您的样本数据,我已将其移动到变量中。
DECLARE @Sample TABLE
(
ID INT,
[Value] VARCHAR(8)
)
;
INSERT INTO @Sample
(
ID,
[Value]
)
VALUES
(1,'a1¦aa¦a2'),
(1,'b1¦aa¦b2'),
(1,'b3¦tt¦b3'),
(2,'a2¦aa¦z1'),
(2,'b2¦tt¦z2'),
(2,'b3¦tt¦z3')
;
我不完全确定我理解这个要求。所以我最好解释一下我做了什么。此查询将返回共享ID
且Part1
2的所有ID
1。
WITH CTE AS
(
/* Amended OP original query.
* WHERE clause dropped and
* table name replaced with var.
*/
SELECT
Id,
SUBSTRING(MT.Value, 1, CHARINDEX ( '¦' ,MT.Value)-1) AS [part1],
SUBSTRING(MT.Value, CHARINDEX ( '¦' ,MT.Value)+1, 2) AS [part2],
RIGHT(MT.Value,CHARINDEX('¦',REVERSE(MT.Value),0)-1) AS [part3]
FROM
@Sample MT
)
SELECT
*
FROM
CTE AS cte1
INNER JOIN CTE AS cte2 ON cte2.part1 = cte1.part1
WHERE
cte1.ID = 1
AND cte2.ID = 2
;