如何控制 JSON_ARRAYAGG 如何对结果进行排序

cot*_*ros 6 mysql json

我正在测试 MySQLJSON_ARRAYJSON_ARRAYAGG函数,以便将一些应用程序昂贵的进程移动到 SQL 存储函数。

在下面的电子商务应用程序示例中,我尝试检索用户的购物车,而不是作为来自 cart_items 表的行结果集,而是作为包含 Javascript 回调函数呈现购物车所需的所有信息的 JSON 字符串。

我有一张cart包含一般购物车信息的表格

create table user_cart (
  cart_id  integer unsigned primary key,
  user_id  integer unsigned not null,
);
Run Code Online (Sandbox Code Playgroud)

cart_item明细表,

create table cart_item (
  cart_item_id  integer unsigned primary key auto_increment,
  cart_id       integer unsigned not null,
  product_id    integer unsigned not null,

  qty           integer unsigned not null,
  ref           varchar(15) not null,

  -- total
  base          double default 0.0,
  tax           double default 0.0,
  tax_pct       double default 0.0,
  total         double default 0.0,

  foreign key (cart_id) references user_cart(cart_id),
);
Run Code Online (Sandbox Code Playgroud)

将以下数据插入表中

insert into user_cart(user_id, cart_id) values
(9001, 30201),
(9001, 30202);
(9001, 30203),
(9001, 30245),
(9001, 30300),
(9001, 30344);

insert into cart_item(cart_id, qty, product_id, ref, base, tax, tax_pct, total) values
(30201, 10, 90000, 'BBB-90000', 12, 2.52, 0.21, 14.52),
(30201, 20, 33333, 'JKL-33333', 11.78, 2.4738, 0.21, 14.2538),
(30201, 10, 12211, 'BBB-12211', 78.05, 16.3905, 0.21, 94.4405),
(30201, 1,  12821, 'XXX-12821', 28.02, 5.8842, 0.21, 33.9042),
(30201, 5,  10000, 'DLO-10000', 0.68, 0.1428, 0.21, 0.8228),
(30201, 10, 12345, 'XXX-12345', 99.95, 20.9895, 0.21, 120.9395),
(30201, 1,  11590, 'DLO-11590', 100.25, 21.0525, 0.21, 121.3025),
(30201, 1,  45000, 'NKN-45000', 1.12, 0.2352, 0.21, 1.3552),
(30201, 1,  14999, 'DLO-14999', 1.9, 0.399, 0.21, 2.299),
(30201, 3,  98700, 'XYI-98700', 1.67, 0.3507, 0.21, 2.0207),
(30201, 1,  10391, 'BBB-10391', 3.45, 0.7245, 0.21, 4.1745),
(30201, 1,  11021, 'DLO-11021', 4, 0.84, 0.21, 4.84),
(30201, 2,  11884, 'BBB-11884', 18.2, 3.822, 0.21, 22.022);
Run Code Online (Sandbox Code Playgroud)

然后,我尝试检索用户的购物车项目,30201我写了以下选择语句

select json_arrayagg(jobj) from (
  select json_array(product_id, qty, ref, base, tax, tax_pct, total) as jobj
  from cart_item where cart_id = 30201
) as jarray\G
Run Code Online (Sandbox Code Playgroud)

返回

*************************** 1. row ***************************
json_arrayagg(jobj): [[90000, 10, "BBB-90000", 12.0, 2.52, 0.21, 14.52], [33333, 20, "JKL-33333", 11.78, 2.4738, 0.21, 14.2538], [12211, 10, "BBB-12211", 78.05, 16.3905, 0.21, 94.4405], [12821, 1, "XXX-12821", 28.02, 5.8842, 0.21, 33.9042], [10000, 5, "DLO-10000", 0.68, 0.1428, 0.21, 0.8228], [12345, 10, "XXX-12345", 99.95, 20.9895, 0.21, 120.9395], [11590, 1, "DLO-11590", 100.25, 21.0525, 0.21, 121.3025], [45000, 1, "NKN-45000", 1.12, 0.2352, 0.21, 1.3552], [14999, 1, "DLO-14999", 1.9, 0.399, 0.21, 2.299], [98700, 3, "XYI-98700", 1.67, 0.3507, 0.21, 2.0207], [10391, 1, "BBB-10391", 3.45, 0.7245, 0.21, 4.1745], [11021, 1, "DLO-11021", 4.0, 0.84, 0.21, 4.84], [11884, 2, "BBB-11884", 18.2, 3.822, 0.21, 22.022]]
1 row in set (0,00 sec)
Run Code Online (Sandbox Code Playgroud)

扫描结果可以很容易看出product_ids的出现顺序如下:90000, 33333, 12211, 12821, 10000, 12345,...,这是在数据库中插入项目的真实顺序。

但是,当我尝试以不同的顺序检索项目时,假设 order by product_id,我得到的结果与以前相同,就好像该order by子句被忽略一样。

select json_arrayagg(jobj) from (   
  select json_array(product_id, qty, ref, base, tax, tax_pct, total) as jobj   
  from cart_item where cart_id = 30201 order by product_id 
) as jarray\G
Run Code Online (Sandbox Code Playgroud)
*************************** 1. row ***************************
json_arrayagg(jobj): [[90000, 10, "BBB-90000", 12.0, 2.52, 0.21, 14.52], [33333, 20, "JKL-33333", 11.78, 2.4738, 0.21, 14.2538], [12211, 10, "BBB-12211", 78.05, 16.3905, 0.21, 94.4405], [12821, 1, "XXX-12821", 28.02, 5.8842, 0.21, 33.9042], [10000, 5, "DLO-10000", 0.68, 0.1428, 0.21, 0.8228], [12345, 10, "XXX-12345", 99.95, 20.9895, 0.21, 120.9395], [11590, 1, "DLO-11590", 100.25, 21.0525, 0.21, 121.3025], [45000, 1, "NKN-45000", 1.12, 0.2352, 0.21, 1.3552], [14999, 1, "DLO-14999", 1.9, 0.399, 0.21, 2.299], [98700, 3, "XYI-98700", 1.67, 0.3507, 0.21, 2.0207], [10391, 1, "BBB-10391", 3.45, 0.7245, 0.21, 4.1745], [11021, 1, "DLO-11021", 4.0, 0.84, 0.21, 4.84], [11884, 2, "BBB-11884", 18.2, 3.822, 0.21, 22.022]]
1 row in set (0,00 sec)
Run Code Online (Sandbox Code Playgroud)

预计该order by条款将在何处生效?是否有任何修饰符,JSON_ARRAYAGG因为它似乎在 Oracle DB 中?

小智 2

如果您有在数据库中进行排序的硬功能要求,那么这是一件有趣的事情。然后就可以了,您可以通过首先按照您想要的顺序将数据插入到临时表中来使用 MySQL 的“功能”。

drop temporary table if exists temp_results;
create temporary table temp_results
select
    json_array(product_id, qty, ref, base, tax, tax_pct, total) as jobj
from cart_item
where cart_id = 30201
    order by
    product_id;
Run Code Online (Sandbox Code Playgroud)

然后你可以执行 json_arrayagg func ,它会按照你想要的顺序排列。

select
    json_arrayagg(jobj)
from temp_results tr;
Run Code Online (Sandbox Code Playgroud)