如何从 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,*';
我有一个 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,*';