您无法在单个查询中获得所需的结果,至少在当前版本的 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 的错误方式。我知道您说过您致力于这种结构,但从长远来看,您会发现它比修复架构所需的工作更多。
另请参阅我对在数据库列中存储分隔列表真的那么糟糕吗?