场景描述
假设我们有以下需求:

(图片来源网络,侵删)
- 数据表:
dede_archives(织梦默认的文章主表) - 目标字段:
flag(这个字段通常用于标记文章的状态,如“头条”、“推荐”、“跳转”等,它是一个位运算字段或逗号分隔的字符串字段) - 任务: 查询出
flag字段不包含某个特定值(不包含c,代表“跳转”)的所有文章。
在织梦CMS中,flag 字段通常是一个逗号分隔的字符串,
h(头条)c(跳转)p(图片)h,c(既是头条又是跳转)- (空字符串) (普通文章)
我们的目标是找出所有 flag 字段里没有 c 的记录。
使用 NOT LIKE (最常用,推荐)
这是最直观、最常用的方法,通过模式匹配来排除包含特定字符的记录。
SQL 查询语句
SELECT * FROM `dede_archives` WHERE `flag` NOT LIKE '%c%';
语句解析
SELECT * FROM dede_archives: 从文章主表dede_archives中查询所有字段。WHERE flag NOT LIKE '%c%': 这是核心的筛选条件。LIKE: SQL中的模式匹配操作符。- 是一个通配符,代表任意长度的任意字符(包括零个字符)。
'%c%': 这个模式表示“字符串中任意位置包含字符c”。NOT LIKE: 对LIKE的逻辑取反,表示“不匹配”后面的模式。NOT LIKE '%c%'的意思就是:flag字段的值中,任意位置都不包含字符c。
优点
- 简单直观:语法简单,易于理解和记忆。
- 高效:对于大多数情况,数据库索引可以很好地支持
LIKE和NOT LIKE查询。
注意事项
- 大小写敏感:此查询是大小写敏感的,如果你的
flag字段里可能有C(大写),而你又想排除它,需要使用COLLATE或同时查询大小写,-- 排除小写 c 和大写 C SELECT * FROM `dede_archives` WHERE `flag` NOT LIKE '%c%' AND `flag` NOT LIKE '%C%';
- 精确匹配:如果你只想排除只有
c这一个值的记录,而保留h,c这样的记录,这个方法就不适用了,但对于排除某个标记,这个方法完全正确。
使用 FIND_IN_SET() (更精确,适用于逗号分隔)
FIND_IN_SET() 函数是专门为处理逗号分隔的字符串而设计的,它比 LIKE 更精确。

(图片来源网络,侵删)
SQL 查询语句
SELECT * FROM `dede_archives` WHERE NOT FIND_IN_SET('c', `flag`);
语句解析
FIND_IN_SET('c', flag): 这个函数会检查逗号分隔的字符串flag中,是否包含子串'c'。- 如果包含,它返回该子串的位置(一个大于0的整数)。
- 如果不包含,它返回
0。
NOT FIND_IN_SET('c', flag): 对函数的返回结果取反,当FIND_IN_SET返回0(即不包含)时,NOT条件为真,该记录就会被选中。
优点
- 非常精确:它只匹配完整的逗号分隔项,而不会误匹配。
FIND_IN_SET('c', 'a,b,c')会返回3(真),而FIND_IN_SET('c', 'abc')会返回0(假)。LIKE则会把'abc'也匹配出来。 - 可读性好:意图非常明确,就是在一个集合中查找某个元素。
适用场景
- 当
flag字段明确是逗号分隔的字符串列表时,这是最佳选择。
使用 REGEXP (正则表达式,功能最强大)
如果你需要更复杂的匹配逻辑,可以使用正则表达式。
SQL 查询语句
SELECT * FROM `dede_archives` WHERE `flag` NOT REGEXP 'c';
语句解析
REGEXP: 是REGEXP的缩写,用于正则表达式匹配。'c': 这是一个简单的正则表达式,表示匹配字符c。NOT REGEXP 'c': 表示flag字段的值不匹配正则表达式'c',即不包含字符c。
更严格的正则表达式(推荐)
为了避免匹配到 c 出现在其他标记中的情况(虽然 flag 通常是单个字符,但为了严谨),可以使用更精确的正则表达式,确保 c 是一个独立的标记:
-- 排除 'c',但允许 'c' 出现在开头、中间或结尾,前后可以是逗号或字符串边界 SELECT * FROM `dede_archives` WHERE `flag` NOT REGEXP '(^|,)c(,|$)';
(^|,): 匹配字符串的开始位置^或者一个逗号 。c: 匹配字符c。- 匹配一个逗号 或者字符串的结束位置 。
这个正则表达式确保 c 是作为一个独立的标记存在的,逻辑上与方法二 FIND_IN_SET 完全等价。
优点
- 功能强大:可以处理极其复杂的文本匹配逻辑。
- 灵活性高:比
LIKE和FIND_IN_SET更灵活。
缺点
- 语法复杂:正则表达式语法相对难懂。
- 性能稍差:对于简单的匹配,正则表达式的性能通常不如
LIKE或专门的函数如FIND_IN_SET。
实际应用:在织梦后台执行SQL
在织梦CMS后台,你可以很方便地执行这些SQL语句来批量处理数据。

(图片来源网络,侵删)
- 登录织梦后台。
- 在顶部菜单栏找到并点击 【系统】 -> 【SQL命令行工具】。
- 你会看到一个文本框,在这里可以输入你的SQL语句。
- 选择操作类型:
- 如果你只想查看结果,选择
查询。 - 如果你已经确认无误,要执行操作(如删除、修改),选择
执行。
- 如果你只想查看结果,选择
- 输入SQL语句:将上面任意一种方法的SQL语句粘贴到文本框中。
- 提交:点击【确定】按钮。
示例:使用 FIND_IN_SET 查询不包含 c 的文章
-- 查询语句(用于预览结果)
SELECT id, title, flag FROM dede_archives WHERE NOT FIND_IN_SET('c', flag);
-- 如果你确定要删除这些不包含 'c' 的文章(危险操作!请先备份数据!)
-- DELETE FROM dede_archives WHERE NOT FIND_IN_SET('c', flag);
⚠️ 重要安全警告:
- 备份数据!备份数据!备份数据! 在执行任何
DELETE或UPDATE操作之前,务必备份数据库,建议先使用SELECT查询,确认查询结果就是你想要的,然后再将SELECT改为DELETE或UPDATE。 - 小心执行:
DELETE操作是不可逆的,一旦执行,数据将永久丢失。
总结与推荐
| 方法 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|
NOT LIKE '%c%' |
简单、直观、高效 | 可能不够精确,大小写敏感 | 快速、简单的排除,不关心大小写和精确匹配时。 |
NOT FIND_IN_SET() |
精确、高效、可读性好 | 仅适用于逗号分隔的字符串 | 强烈推荐,当 flag 是逗号分隔的标记时,这是最理想的选择。 |
NOT REGEXP |
功能最强大,逻辑最灵活 | 语法复杂,性能稍差 | 需要处理非常复杂、非标准的匹配逻辑时。 |
对于织梦CMS的 flag 字段,FIND_IN_SET() 是最专业、最可靠的选择,其次是 NOT LIKE,因为它足够简单且能满足绝大多数需求。
