【问题标题】:mysql: finding the shortest and the longest value within an mysql-columnmysql:在 mysql 列中查找最短和最长的值
【发布时间】:2017-08-08 12:12:20
【问题描述】:

我有一个关于在 MySQL-Column "values" 的连接字符串中查找最短和最长值的问题。 问题,列中的值用“|”连接并且可能会有所不同。

表:

ID  |  values 
----------------------------------------
A   |  12.1|11.23|134.44
B   |  11.134|1.3|34.5|152.12|1.31313|134.331|12.31
C   |  34.11|1.34|343412.2|13......

问题是:是否有一些简单的方法可以仅通过本机 mysql 查询找到(最短和最长)值,而不使用 Java 或 PHP 等任何语言。

谢谢

【问题讨论】:

  • 修复您的数据结构,使其具有一个表,其中每个值和一个值都有一个单独的行。
  • 这不是 RDBMS 框架内的有效数据集
  • 这些值代表什么?请添加预期的输出。
  • 我知道这个表结构并不代表现代数据存储的观点,但是没有机会改变数据结构,我们必须处理遗留代码和结构。

标签: mysql indexing substring find-in-set


【解决方案1】:

您无法在单个查询中获得所需的结果,至少在当前版本的 MySQL 中无法获得。原因是在您知道最大长度之前,您无法形成查询以从未知长度的分隔字符串中获取单个元素。

首先找出最长列表中有多少个元素:

select max(length(`values`)-length(replace(`values`, '|', ''))) as max from t;
+------+
| max  |
+------+
|    6 |
+------+

现在您知道您需要在分隔字符串中测试多达 7 个“字段”。没有办法用可变数量的联合查询来形成 SQL。语法必须在准备时固定,所以你需要知道有多少。

select id, substring_index(substring_index(`values`, '|', 1), '|', -1) as element from t
union
select id, substring_index(substring_index(`values`, '|', 2), '|', -1) from t
union
select id, substring_index(substring_index(`values`, '|', 3), '|', -1) from t
union
select id, substring_index(substring_index(`values`, '|', 4), '|', -1) from t
union
select id, substring_index(substring_index(`values`, '|', 5), '|', -1) from t
union
select id, substring_index(substring_index(`values`, '|', 6), '|', -1) from t
union
select id, substring_index(substring_index(`values`, '|', 7), '|', -1) from t;    

+------+----------+
| id   | element  |
+------+----------+
| A    | 12.1     |
| A    | 11.23    |
| A    | 134.44   |
| B    | 11.134   |
| B    | 1.3      |
| B    | 34.5     |
| B    | 152.12   |
| B    | 1.31313  |
| B    | 134.331  |
| B    | 12.31    |
| C    | 34.11    |
| C    | 1.34     |
| C    | 343412.2 |
| C    | 13       |
+------+----------+

现在使用上面的查询作为子查询,你可以找到最长或最短的:

(select id, element from (...subquery...) as t1 order by length(element) asc limit 1)
union
(select id, element from (...subquery...) as t2 order by length(element) desc limit 1)

+------+----------+
| id   | element  |
+------+----------+
| C    | 343412.2 |
| C    | 13       |
+------+----------+

我同意其他人的意见,即这确实是使用 RDBMS 的错误方式。我知道您说过您致力于这种结构,但从长远来看,您会发现它比修复架构所需的工作更多。

另见我对Is storing a delimited list in a database column really that bad?的回复

【讨论】:

  • 谢谢!这就是我一直在寻找的答案。
【解决方案2】:

最大长度

select * from table order by length(column_name) DESC LIMIT 0,1

最小长度

select * from table order by length(column_name) ASC LIMIT 0,1

如果这不是您想要的,请将您的 SQL 查询添加到问题中。

【讨论】:

  • 我正在寻找字符串中的最短/最长值,而不是字符串长度本身。例如第二行的值,1.3 将是最短的值....
【解决方案3】:

SQL 对单元格中的值数组不友好。重构架构;那么解决方案就很简单了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-22
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-27
    • 2017-12-29
    相关资源
    最近更新 更多