【问题标题】:Sort a field of array upon mysql query [duplicate]根据mysql查询对数组字段进行排序[重复]
【发布时间】:2020-08-31 12:00:48
【问题描述】:

我有一个字段:例如包含 19、2、23 的用户 ID,我根据任意添加到房间的用户 ID 填充该字段。我根据这些用户标识列出了相应的名称。

现在我从这个查询中得到 Richard, Evan, James (19 = Richard, 2 = Evan, 23 = James)。

我想做的是在查询时对数组(字段)进行排序,使其为 2、19、23,并返回名称 Evan、Richard、James。

所以查询看起来像这样:

    SELECT c.*,c.NAME as PAGE, ASORT(c.USERIDS) as USERIDS, p.* 
    FROM TBL_CONTENT c, TBL_PAGE p 
    WHERE c.PAGEID = p.ID AND FIND_IN_SET(?, c.USERIDS) 

应该看起来像(帮我解决这个问题)?

当然,ASORT 函数不存在 - 我只是将它作为我正在尝试做的一个示例。

这里有什么帮助吗? 谢谢!

【问题讨论】:

  • 您首先不应该将逗号分隔的列表放在表格列中。如果你把它放在一个单独的表中,你可以使用GROUP_CONCAT 和它的ORDER BY 选项。
  • 那为什么 FIND_IN_SET 甚至是一个函数呢?
  • 因为人们多年来一直在犯这个错误,而 MySQL 选择了适应他们。
  • 但是你可以用它们做的事情非常有限,排序不是其中之一。
  • 你用的是哪个mysql版本?

标签: mysql arrays sorting


【解决方案1】:

这适用于 mysql 8

对于 mysql 5.x,你需要更多的代码来做到这一点

SET @a = '19,2,23';

SELECT GROUP_CONCAT(ord ORDER BY ord) 
FROM
(select  CAST(num as UNSIGNED) ord
from (SELECT @a as names) t
join json_table(
  replace(json_array(t.names), ',', '","'),
  '$[*]' columns (num varchar(50) path '$')
) j) z1

结果

# GROUP_CONCAT(ord ORDER BY ord)
2,19,23

对于Mysql 5.x 可以使用函数

DELIMITER $$
CREATE DEFINER=`root`@`localhost` FUNCTION `fn_split_stringnumbers_and_sort`(_text TEXT) RETURNS text CHARSET utf8mb4
    DETERMINISTIC
BEGIN
SET @text = _text;
SELECT 
GROUP_CONCAT((name+0) ORDER BY (name +0)) INTO @output
FROM
(
select
  SUBSTRING_INDEX(SUBSTRING_INDEX(t1.name, ',', numbers.n), ',', -1) name
from
  (select 1 n union all
   select 2 union all select 3 union all
   select 4 union all select 5) numbers INNER JOIN (SELECT @text as name) t1
  on CHAR_LENGTH(t1.name)
     -CHAR_LENGTH(REPLACE(t1.name, ',', ''))>=numbers.n-1
order by  n
) t2;

RETURN @output;
END$$
DELIMITER ;

所以这个查询

SET @a = '19,2,23';
SELECT fn_split_stringnumbers_and_sort(@a);

结果相同

# fn_split_stringnumbers_and_sort(@a)
2,19,23

注意 这个函数只会分割 5 个逗号分隔的数字,如果你有更多,你必须用更多的 UNION 增加表

【讨论】:

  • 这在 5.7.26 中可行吗?还是严格来说是 8.x?
  • no JSON_Table 仅在 mysql 8 中有效,但您可以使用我编写的新功能,请查看此功能仅对 5 个数字进行排序的原因,如果您有更多,请在表编号中添加更多联合跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-15
  • 2012-06-15
  • 2011-10-28
  • 2017-04-02
  • 2017-06-15
  • 1970-01-01
  • 2016-03-17
相关资源
最近更新 更多