使用另一列中的子串数填充列

时间:2013-05-21 14:04:11

标签: mysql

我有两张桌子“A”和“B”。表“A”有两列“Body”和“Number”。 “Number”列是空的,目的是填充它。

表A:正文/数字

ABABCDEF /
IJKLMNOP /
QRSTUVWKYZ /

表“B”只有一列:

表B:值

AB
CD
QR

以下是我正在寻找的结果:

ABABCDEF / 3
IJKLMNOP / 0
QRSTUVWKYZ / 1

换句话说,我想创建一个查询,为“Body”列中的每个字符串查找“Values”列中的子字符串出现次数。

你怎么建议我这样做?

2 个答案:

答案 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, '%')
              )