我有下一个子查询:
Array<Point>
我需要用|分隔所有结果直到我达到130个字符,但我的问题是,如果最后结果不适合示例:
我得到前30个字符,但最后的结果不合适,我得到: RESULT1 | RESULT2 | result3 |结果
我想要这个: RESULT1 | RESULT2 | result3
(如果结果不合适,请删除该结果中的所有字符)
谢谢你们
答案 0 :(得分:0)
试试这个
更新了GROUP_CONCAT并添加了另一个步骤来删除超过30个最大长度的无关数据
SELECT
@str:= left(GROUP_CONCAT( DISTINCT PT.Factura SEPARATOR '|'), 30)
FROM
vt_pedimentos P
INNER JOIN
vt_partidas PT
ON PT.Pedimento = P.ID
WHERE
P.ID = 130;
-- to check whether the last or truncated text exists in the table otherwise remove
select
@str:= left(@str,
(
length(@str) - length(reverse(left(reverse(@str), locate('|', reverse(@str)) - 1)))
)
- 1)
FROM
vt_pedimentos P
where
NOT EXISTS
(
select
1
from
vt_partidas PT
where
PT.Factura = reverse(left(reverse(@str), locate('|', reverse(@str)) - 1))
)
and P.ID = 130;
进一步增强 - 将它添加到一个sql语句
答案 1 :(得分:0)
字符串操作不是SQL表达式的强项。
但是这样的事情应该这样做:
SELECT
IF(CHAR_LENGTH( GROUP_CONCAT(DISTINCT PT.Factura SEPARATOR '|') ) < 130
, GROUP_CONCAT(DISTINCT PT.Factura SEPARATOR '|')
, SUBSTRING_INDEX(
SUBSTR( GROUP_CONCAT(DISTINCT PT.Factura SEPARATOR '|') ,1,130)
, '|'
, CHAR_LENGTH( SUBSTR( GROUP_CONCAT(DISTINCT PT.Factura SEPARATOR '|') ,1,130) )
-CHAR_LENGTH(REPLACE(SUBSTR( GROUP_CONCAT(DISTINCT PT.Factura SEPARATOR '|') ,1,130),'|',''))
)
)
那很复杂。如果我们用占位符替换GROUP_CONCAT
表达式,将更容易解密。我们有res
代表GROUP_CONCAT(DISTINCT PT.Factura SEPARATOR '|')
表达式。
SELECT
IF(CHAR_LENGTH( res ) < 130
, res
, SUBSTRING_INDEX(
SUBSTR( res ,1,130)
, '|'
, CHAR_LENGTH( SUBSTR( res ,1,130) )
-CHAR_LENGTH(REPLACE(SUBSTR( res ,1,130),'|',''))
)
)
仍然很丑,但更好。让我们打破它。
如果res
中的字符数小于130,我们就完成了。只需返回res。
否则,我们需要将res修剪为130个字符,我们可以使用SUBSTRING函数来做到这一点。
现在,我们要修剪最后的|
和以下字符。为此,我们可以计算|
个分隔符的数量。然后我们知道最后一个是哪一个。
(我们可以通过用空字符串替换所有分隔符来获取分隔符的计数,然后获取该字符串的长度,并从原始字符串的长度中减去该字符串。差异是该字符串的总长度。删除了分隔符。
然后我们可以在SUBSTRING_INDEX
函数中使用该差异来返回最后一个分隔符之前的所有字符。
这不是一个漂亮的解决方案。但它确实实现了满足规范的算法。