Mysql
 sql >> Base de données >  >> RDS >> Mysql

Somme agrégée MySQL des objets JSON

Mise à jour :OK

Tout d'abord, je recommanderais certainement de normaliser un peu les données.Avez-vous essayé de stocker uniquement les objets dans la colonne des détails ?Si vous aviez besoin de stocker des groupes de données avec chaque ID d'échantillon, vous pouvez utiliser une table relative. C'est-à-dire :)

Échantillon

id int incrémentation automatique

mysql> create table Sample (id int(11) not null auto_increment, primary key(id));

Détails

sample_id entre enregistrement json

mysql> create table Details (sample_id int(11), record json);

Remplissez vos données

insert into Sample (id) values (1);
insert into Sample (id) values (2);

insert into Details (sample_id, record) values 
  (1, '{"id": 1, "name": "T1", "amount": "34.34", "percentage": "45"}'), 
  (1, '{"id": 3, "name": "T3", "amount": "30.34", "percentage": "45"}'), 
  (1, '{"id": 2, "name": "T2", "amount": "14.34", "percentage": "15"}');

insert into Details (sample_id, record) values 
  (2, '{"id": 1, "name": "T1", "amount": "34.34", "percentage": "45"}'),
  (2, '{"id": 2, "name": "T2", "amount": "30.34", "percentage": "45"}'),
  (2, '{"id": 4, "name": "T4", "amount": "14.34", "percentage": "15"}');

Ensuite, vous pouvez faire quelque chose comme

SELECT (
  JSON_OBJECT('id', id, 'amount', amount, 'percentage', percentage)
) FROM (
  SELECT 
    JSON_EXTRACT(record, "$.id") as id, 
    SUM(JSON_EXTRACT(record, "$.amount")) as amount, 
    AVG(JSON_EXTRACT(record, "$.percentage")) as percentage
  FROM Details 
  GROUP BY JSON_EXTRACT(record, "$.id")
) as t 

Résultats

+---------------------------------------------------------------------+
| (JSON_OBJECT('id', id, 'amount', amount, 'percentage', percentage)) |
+---------------------------------------------------------------------+
| {"id": 1, "amount": 68.68, "percentage": 45}                        |
| {"id": 2, "amount": 44.68, "percentage": 30}                        |
| {"id": 3, "amount": 30.34, "percentage": 45}                        |
| {"id": 4, "amount": 14.34, "percentage": 15}                        |
+---------------------------------------------------------------------+

Si vous ne voulez pas (ou ne pouvez pas) utiliser un ensemble de données normalisé, alors vous pourriez peut-être envisager d'écrire une procédure stockée qui boucle sur vos colonnes de détails et agrège les données pour chacune, avec une requête qui agrège les deux jeux de données.