4

我有两个表“A”和“B”。表“A”有两列“Body”和“Number”。“数字”列是空的,目的是填充它。

表 A:正文/编号

ABABCDEF /
IJKLMNOP /
QRSTUVWKYZ /

表“B”只有一列:

表 B:值

AB
CD
QR

这是我正在寻找的结果:

ABABCDEF / 3
IJKLMNOP / 0
QRSTUVWKYZ / 1

换句话说,我想创建一个查询,对于“Body”列中的每个字符串,“Values”列中的子字符串出现了多少次。

你会如何建议我这样做?

4

2 回答 2

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 Fiddle 。

现在解释...

内部查询将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

如果你只计算这些,你只会得到字符串的2值,因为它只是寻找ABABCDEF子字符串的存在并且没有考虑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防止这种情况。

于 2013-05-21T14:51:18.663 回答
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, '%')
              )
于 2013-05-21T15:20:54.823 回答