如何在sql中选择与regexp匹配的单词?

时间:2017-10-04 13:02:44

标签: mysql sql

我正在尝试使用sql中的REGEXP从字段中提取主题标签。现在我正在做这个查询

SELECT caption FROM posts WHERE caption REGEXP "#[a-zA-Z0-9_]+"

但我想提取与此模式匹配的特定单词。

就像我的数据库中有以下条目一样

id caption         user
1  #hi i'm here    2
2  hello #hi there 3
3  i'm x #hi       4
4  I'm #Driving    2
5  I #love #food   6

现在我的查询正在返回

caption
#hi i'm here
hello #hi there
i'm x #hi
I'm #Driving
I #love #food

但我想要

tag
#hi
#Driving
#love
#food

我怎样才能实现这一点。

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

创建表/插入数据

CREATE TABLE Table1
    (`id` INT, `caption` VARCHAR(255), `user` INT)
;

INSERT INTO Table1
    (`id`, `caption`, `user`)
VALUES
    (1, '#hi i''m here', 2),
    (2, 'hello #hi there', 3),
    (3, 'i''m x #hi', 4),
    (4, 'I''m #Driving', 2),
    (5, 'I #love #food', 6)
;

您可以使用SUBSTRING_INDEX(SUBSTRING_INDEX(caption, ' ', 1), ' ', -1)拆分字幕中的字词,以获取第一个字SUBSTRING_INDEX(SUBSTRING_INDEX(caption, ' ', 2), ' ', -1)以获取第二个字。

但是如何让它变得动态,以便你可以分割更多的单词。

首先使用SQL创建一个数字生成器。 此查询将生成1到100之间的数字列表

<强>查询

SELECT
  @number := @number + 1 AS number
FROM (
  (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) row1
  CROSS JOIN
  (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) row2
  CROSS JOIN 
  (SELECT @number:=0) AS init_user_params
)  

<强>结果

number  
--------
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      ...
      ...
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
     100

现在我们可以使用Table1(在我们的示例中)CROSS JOIN我们的数字生成列表 这将生成(表计数)* 100条带有重复记录的记录。 并在SUBSTRING_INDEX(SUBSTRING_INDEX(caption, ' ', [word offset]), ' ', -1)中使用生成的数字列表,如此

<强>查询

SELECT  
  DISTINCT #remove duplicates
    SUBSTRING_INDEX(SUBSTRING_INDEX(caption, ' ', numbers.number), ' ', -1) AS tag
FROM (

  SELECT
    @number := @number + 1 AS number
  FROM (
    (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) row1
     CROSS JOIN
    (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) row2
     CROSS JOIN 
    (SELECT @number:=0) AS init_user_params
  )  
) 
 AS numbers
CROSS JOIN Table1
WHERE
 SUBSTRING_INDEX(SUBSTRING_INDEX(caption, ' ', numbers.number), ' ', -1) LIKE '#%' #we only want words starting with #
ORDER BY 
 Table1.id ASC 

<强>结果

tag       
----------
#hi       
#Driving  
#love     
#food     

备注

  1. 此查询仅在标题等于或少于100个字时才有效
  2. 此查询在较小的表上非常快。在较大的桌子上,这不会很好地扩展,因为关闭了CROSS JOIN
  3. 你真的应该有一个存储主题标签的表。