MySQL根据列中子字符串的数量选择?

时间:2011-10-18 23:44:34

标签: mysql

假设我有两张桌子(我正试图从表格中删除与问题无关的所有内容并制作一些样本,所以请耐心等待:)

    ___________________         ________________________
    |File             |         |Content               |
    |_________________|         |______________________|
    |ID Primary Key   | 1     * |ID Primary Key        |
    |URL Varcher(255) |---------|FileID Foreign Key    |
    |_________________|         |    ref File(ID)      |
                                |FileContent Text      |
                                |______________________|

文件有一个网址。每个文件可能有许多内容项。

我需要使用这些表创建一个查询,我遇到了一些问题。我基本上希望查询简单地说:

“选择文件网址,子字符串的总和”X“出现在与该文件相关的所有内容条目中。”

我对SQL选择非常好,但我对聚合函数不太好,它让我失望。非常感谢任何帮助:)

2 个答案:

答案 0 :(得分:1)

此解决方案尝试使用REGEXP匹配子字符串。 REGEXP如果匹配则返回1,否则返回0,因此SUM()为总数。 REGEXP似乎有点矫枉过正,但允许比简单的子串更复杂的匹配。

SELECT
  File.ID,
  File.URL,
  SUM(Content.FileContent REGEXP 'substring') AS numSubStrs
FROM File LEFT JOIN Content ON File.ID = Content.ID
GROUP BY File.ID, File.URL;

如果不再需要更复杂的匹配模式,使用LIKECOUNT(*)代替SUM(),则更简单的方法:

SELECT
  File.ID,
  File.URL,
  COUNT(*) AS numSubStrs
FROM File LEFT JOIN Content ON File.ID = Content.ID
WHERE Content.FileContent LIKE '%substring%'
GROUP BY File.ID, File.URL;

请注意使用LEFT JOIN,当Content中实际没有任何条目时,{{1}}应生成0。

答案 1 :(得分:1)

查询效率不高但可能会给你一个提示:

SELECT url, cnt
FROM (
  SELECT
    f.id,
    IFNULL(
      SUM(
        (LENGTH(c.text) - LENGTH(REPLACE(c.text, f.url, '')))/LENGTH(f.url)
      ),
      0
    ) as cnt
  FROM file c
  JOIN content c ON f.id = c.fileid
  GROUP BY f.id
) cnts JOIN file USING(id);

要附加内容表中没有匹配项的文件,您可以在UNION ALL子查询中LEFT JOIN使用剩余的cnts