如何检查逗号分隔字段的每个元素中是否存在一个字段中的字符串

时间:2019-05-01 12:32:27

标签: mysql sql regex

我有一个包含两个字段的表。第一个是类型name的{​​{1}}。第二个包含一个或多个用逗号分隔的字符串(但可以包含一个完全没有逗号的字符串)

我想构建一个查询,以了解{{1}中的每个逗号分隔的字符串中是否不存在string字段中的字符串}字段。

示例1:

name

所有用逗号分隔的字符串都包含单词names。因此查询应不返回此行。

但是,示例2:

---------------------------------------------------------
name          names
---------------------------------------------------------
myname        xmyname,myname,mynamey

应退回。因为x不包含我的名字。

条件是,如果myname字段中逗号分隔的字符串的每个中都不存在字段--------------------------------------------------------- name names --------------------------------------------------------- myname x,myname,mynamey 中的字符串,则返回该行。

这是不正确的,因为此查询在示例2(包含name而不包含names的示例中不会返回true)。

重要说明:

1)那里没有多少个逗号没有限制。可以是0个逗号或更多。怎么处理呢?

2)字符串是变量。字符串并非总是x的情况。每行在myname字段中包含一个不同的字符串。

4 个答案:

答案 0 :(得分:0)

此答案开始时给出了错误的REGEXP解决方案。但是,这里最好的做法是修复数据模型,以使names列中的每个名称实际上位于单独的行中:

name     | names
myname   | xmyname
myname   | myname
myname   | mynamey
somename | x
somename | myname
somename | mynamey

现在我们可以做一个简单的汇总查询来回答您的问题:

SELECT name
FROM yourTable
GROUP BY name
HAVING COUNT(CASE WHEN names NOT LIKE CONCAT('%', name, '%') THEN 1 END) > 0;

Demo

答案 1 :(得分:0)

假设“ myname”在两个逗号之间没有出现“ 两次”,则可以计算逗号和“ myname”:

where (length(names) - length(replace(names, ','))) >=
       length(names) - length(replace(names, 'myname', '12345'))

答案 2 :(得分:0)

您可以使用以下SQL查询

SELECT 
name, names
FROM 
`tablename` 
WHERE 
(LENGTH(names) - LENGTH(REPLACE(names, ',', '')) + 1) 
=  
ROUND (   
  (
        LENGTH(names)
        - LENGTH( REPLACE ( names, name, "") ) 
  )/ LENGTH(name)       
);

说明:-

这将为您提供用,分隔多少个单词

(LENGTH(names) - LENGTH(REPLACE(names, ',', '')) + 1) - 

以下内容与每行中的name匹配,并返回找到的次数

 ROUND (   
    (
        LENGTH(names)
        - LENGTH( REPLACE ( names, name, "") ) 
    ) / LENGTH(name)        
)

DEMO

答案 3 :(得分:0)

尝试以下正则表达式:

where not concat(names, ',') regexp replace('^([^,]*{n}[^,]*,)*$', '{n}', name)

db-fiddle demo

如何阅读模式:

内部模式[^,]*{n}[^,]*,的含义

  • 任何非逗号字符[^,]重复了任意次(*表示没有次数或多次)。
  • 后面紧跟着列name的值({n}是一个占位符,将使用replace()函数用实际值替换)
  • 后面跟着任意多次非逗号字符[^,]
  • 后跟逗号

外部模式^({inner_pattern})*$表示

  • 字符串(^)的开头
  • 内部模式重复任意次
  • 跟在字符串末尾($

为实现此目的,在names列(concat(names, ','))后面附加了一个逗号,以便字符串中的每个元素都以逗号结尾。

该模式将确保逗号分隔的字符串中的任何元素都包含name列的值。由于您想要相反的结果,因此我们使用where not ..