如何从类似sql的查询中获取精确值

发布于 2025-01-15 20:43:40 字数 274 浏览 5 评论 0原文

我有一个 Mysql 数据库,其中包含一些类别 ID,它在表中存储逗号分隔的值。

sql 表视图

通过使用 select * from style wherecategories like '%8,% '; 它返回所有以 8 结尾的值。例如,如果表行有两个值,例如 8 和 148,它将返回这两行。但我只想获取包含 8 的行。该怎么做

I have a Mysql database that contains some category ids on it which stores comma-separated values on a table.

sql table view

By using select * from style where categories like '%8,%'; it returns all the values end with 8. For example, if the table rows have two values like 8 and 148 it returns both rows. But I want to get only the rows that contain 8. How to do it

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

↘人皮目录ツ 2025-01-22 20:43:40

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

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

Storing multiple values in a single column is a denormalised design that will almost always cause you problems. However you need to add commas to both sides and compare:

select *
from Style
where concat(',',Categories,',') like '%,8,%';
草莓酥 2025-01-22 20:43:40

和其他人一样:标准化你的数据。但如果你不能,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() 返回正在搜索的值的伪数组中返回 1 到 N 范围内的值。我们需要确保结果大于 0(或将其视为布尔值),以便搜索值“存在”在记录列中。
  • 引擎没有返回 CTE 中的第四个联合值,因为它没有“单独”8 值。
  • 如果我们只搜索 100,它将返回最后一条记录。
  • 该函数的代价是在大型数据集上的性能下降;如果数据被标准化并建立索引,你就不会这样了。
  • 那么为什么会退出呢?对于小型枚举列表或属性。它仍然不理想,但如果你只有几个使用它“可以”有意义。但在非常有限的用例中并且经常被误用。
  • 这种设计违反了第三范式。这就是为什么大多数 RDBMS 设计在提出时都会感到畏缩,因为它不可扩展。
  • 至于为什么人们对多值列感到愤怒:阅读此内容这个

Like everyone else: normalize your data. But if you can't mySQL supports find_in_set() for set datatypes which this appears to be.

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

OR we can use a boolean evaluation and eliminate the > 0

SELECT * FROM CTE where find_in_set(8,categories)  

Giving us:

+------------------------+-------------------+
|      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 |
+------------------------+-------------------+

Notes

  • Find_in_set() returns the Returns a value in the range of 1 to N in the pseudo array of the value being searched. We need to ensure the result is greater than 0 (or treat it as a Boolean) in order for the searched value to "exist" within a record column.
  • The engine didn't return my 4th union value in CTE because it doesn't have an "alone" 8 value
  • If we searched for just 100 it would return that last record.
  • This function comes at a cost of performance on large datasets; which if data was normalized and indexed, you wouldn't have.
  • So why does this exit? For small enumerated lists or properties. It's still not ideal but if you have just a few using it "can" make sense. but in a very limited use case and often is missused.
  • This design violates 3rd normal form. Which is why most RDBMS designs cringe when it's brought up as it's not scalable.
  • as to why people are up in arms about multi value columns: Read this or This
梦里的微风 2025-01-22 20:43:40

您还可以使用 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,*';

You can also use rlike and in fact it is much better than like as it has much more options.

* = 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

And many more options

select * from style where concat(',',categories,',') rlike '*,8,*';
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文