Question

Vous rencontrez des difficultés pour articuler cette sous-requête corrélée. J'ai deux tables tables fictives, foo et bar. Foo a deux champs de foo_id et total_count. la barre a deux champs, secondes et id.

J'ai besoin d'agréger les secondes en bars pour chaque identifiant individuel et de mettre à jour le total_count dans foo. id est une clé étrangère en barre pour foo_id.

J'ai essayé quelque chose de similaire sans trop de chance:

UPDATE foo f1 set total_count = (SELECT SUM(seconds) from bar b1 INNER JOIN foo f2     WHERE b1.foo_id = f2.id) WHERE f1.foo_id = bar.id;
Était-ce utile?

La solution

UPDATE foo f1
SET total_count = (SELECT SUM(seconds)
FROM bar b1 WHERE b1.id = f1.foo_id)

Vous devriez avoir accès à l'ID de foo approprié dans la sous-requête, il n'est donc pas nécessaire de rejoindre la table.

Autres conseils

Dans les grands ensembles de données, les sous-requêtes corrélées peuvent nécessiter beaucoup de ressources. La jonction à une table dérivée contenant les agrégats appropriés peut être beaucoup plus efficace:

create table foo ( foo_id int identity, total_count int default 0 )
create table bar ( foo_id int, seconds int )

insert into foo default values
insert into foo default values
insert into foo default values

insert into bar values ( 1, 10 )
insert into bar values ( 1, 11 )
insert into bar values ( 1, 12 )
    /* total for foo_id 1 = 33 */
insert into bar values ( 2, 10 )
insert into bar values ( 2, 11 )
    /* total for foo_id 2 = 21 */
insert into bar values ( 3, 10 )
insert into bar values ( 3, 19 )
    /* total for foo_id 3 = 29 */

select *
from foo

foo_id      total_count
----------- -----------
1           0
2           0
3           0

update  f
set     total_count = sumsec
from    foo f
        inner join (
                     select foo_id
                          , sum(seconds) sumsec
                     from   bar
                     group by foo_id
                   ) a
            on f.foo_id = a.foo_id

select *
from foo

foo_id      total_count
----------- -----------
1           33
2           21
3           29

Cela ouvre vraiment la porte aux problèmes de cohérence. Vous pouvez envisager de créer une vue plutôt que de transformer la table foo:

CREATE VIEW foo AS
SELECT id, sum(seconds) from bar group by id;

Juste pour offrir une alternative, j'aime utiliser la fonctionnalité astucieuse de mises à jour multi-tables de MySQL:

UPDATE foo SET total_count = 0;

UPDATE foo JOIN bar ON (foo.foo_id = bar.id)
  SET foo.total_count = foo.total_count + bar.seconds;

J'espère avoir bien compris votre question.

Vous avez les tables suivantes:

  • table toto - colonnes: id et total_count
  • table barre - colonnes: foo_id (références foo.id ) et secondes

La requête suivante doit fonctionner (mettez à jour toutes les lignes total_count de la table toto ):

UPDATE foo AS f1
SET total_count = (
  SELECT SUM(seconds) 
  FROM bar INNER JOIN foo 
  WHERE foo_id = f1.id
);

Je ne sais pas trop ce que vous essayez de faire avec votre dernière clause WHERE ( WHERE f1.foo_id = bar.id; ).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top