我有两张桌子“A”和“B”。表“A”有两列“Body”和“Number”。 “Number”列是空的,目的是填充它。
表A:正文/数字
ABABCDEF /
IJKLMNOP /
QRSTUVWKYZ /
表“B”只有一列:
表B:值
AB
CD
QR
以下是我正在寻找的结果:
ABABCDEF / 3
IJKLMNOP / 0
QRSTUVWKYZ / 1
换句话说,我想创建一个查询,为“Body”列中的每个字符串查找“Values”列中的子字符串出现次数。
你怎么建议我这样做?
答案 0 :(得分:2)
这是完成的查询;解释如下:
SELECT
Body,
SUM(
CASE WHEN Value IS NULL THEN 0
ELSE (LENGTH(Body) - LENGTH(REPLACE(Body, Value, ''))) / LENGTH(Value)
END
) AS Val
FROM (
SELECT TableA.Body, TableB.Value
FROM TableA
LEFT JOIN TableB ON INSTR(TableA.Body, TableB.Value) > 0
) CharMatch
GROUP BY Body
有一个SQL小提琴here。
现在解释......
内部查询将TableA
字符串与TableB
子字符串匹配:
SELECT TableA.Body, TableB.Value
FROM TableA
LEFT JOIN TableB ON INSTR(TableA.Body, TableB.Value) > 0
其结果是:
BODY VALUE
-------------------- -----
ABABCDEF AB
ABABCDEF CD
IJKLMNOP
QRSTUVWKYZ QR
如果您只计算这些,那么ABABCDEF
字符串只会得到 2 的值,因为它只是查找子字符串的存在而没有考虑到AB
发生两次。
MySQL似乎没有OCCURS
类型的函数,所以为了计算出现次数,我使用了比较字符串长度与删除目标字符串的长度,除以字符串长度的方法。目标字符串。这是一个解释:
REPLACE('ABABCDEF', 'AB', '') ==> 'CDEF'
LENGTH('ABABCDEF')
==> 8 LENGTH('CDEF')
==> 4 因此,删除所有AB
次出现的字符串的长度为8 - 4或4.将4除以2(LENGTH('AB')
)以获得AB
次出现次数: 2
字符串IJKLMNOP
会搞砸了。它没有任何目标值,因此存在零风险。 CASE
内的SUM
可以防范此问题。
答案 1 :(得分:0)
您想要update
查询:
update A
set cnt = (select sum((length(a.body) - length(replace(a.body, b.value, '')) / length(b.value))
from b
)
这使用一个小技巧来计算给定字符串中b.value
的出现次数。它用空字符串替换每个匹配项,并计算字符串长度的差异。这除以要替换的字符串的长度。
如果你只是想要匹配的数量(所以第一个值是“2”而不是“3”):
update A
set cnt = (select count(*)
from b
where a.body like concat('%', b.value, '%')
)