如何从 sql 之类的查询中获取确切的值

How to get the exact value from sql like query

我有一个 Mysql 数据库,其中包含一些类别 ID,在 table.

上存储以逗号分隔的值

sql table view

通过使用 select * from style where categories like '%8,%'; 它 returns 所有值都以 8 结尾。例如,如果 table 行有两个值,如 8 和 148 它 returns 两者行。但我只想获取包含 8 的行。如何做

在单个列中存储多个值是一种非规范化设计,几乎总是会给您带来麻烦。但是你需要在两边加上逗号并比较:

select *
from Style
where concat(',',Categories,',') like '%,8,%';

像其他人一样:规范化您的数据。但是,如果你不能 mySQL 支持 find_in_set()set 数据类型,这似乎是。

SQL

With CTE as (SELECT 'T-Shrits' as baseCategory, '8,21,75,87,148' categories UNION ALL
SELECT 'T-Shrits' as baseCategory, '8,21,75,87,148'  categories UNION ALL
SELECT 'T-Shrits - Long Sleeve' as baseCategory, '8,21,75,87,148,92'  categories UNION ALL
SELECT 'T-Shrits' as baseCategory, '21,75,87,100,148'  categories)

SELECT * FROM CTE where find_in_set(8,categories) >0

或者我们可以使用布尔值计算并消除 > 0

SELECT * FROM CTE where find_in_set(8,categories)  

给我们:

+------------------------+-------------------+
|      baseCategory      |    categories     |
+------------------------+-------------------+
| T-Shrits               |    8,21,75,87,148 |
| T-Shrits               |    8,21,75,87,148 |
| T-Shrits - Long Sleeve | 8,21,75,87,148,92 |
+------------------------+-------------------+

备注

  • Find_in_set() returns Returns被查找值的伪数组中1到N范围内的一个值。我们需要确保结果大于 0(或将其视为布尔值),以便搜索值“存在”在记录列中。
  • 引擎没有 return 我在 CTE 中的第 4 个联合值,因为它没有“单独的”8 值
  • 如果我们只搜索 100 条,它会 return 最后一条记录。
  • 此功能以大型数据集的性能为代价;如果数据被规范化和索引,你就不会了。
  • 那么为什么会退出呢?对于 small 枚举列表或属性。它仍然不理想,但如果你只有少数人使用它,它“可以”有意义。但在非常有限的用例中并且经常被误用。
  • 这个设计违反了第三范式。这就是为什么大多数 RDBMS 设计在提出时都会畏缩,因为它不可扩展。
  • 关于为什么人们反对多值列:Read this or This

您也可以使用 rlike,实际上它比 like 好得多,因为它有更多选项。

* = repetition of what is in front of it zero or more times
. = Equivalent to any character including none
^ = Anchor start (Forces that begins with ...)
$ = final anchor (forces it to end with ....) 
[ ] = [ RST ] Contain an R or S or T but only one
[^] = DENY IT

还有更多选择

select * from style where concat(',',categories,',') rlike '*,8,*';