Administrateur PHPfrance |
3088 Messages
11 mars 2008, 08:13
Dans ce cas, on reste sur le même principe mais on l'adapte. Au passage, je te recommande fortement d'utiliser les "vrais" schémas et tables de ta base plutôt qu'un exemple théorique, ça permet de cibler plus précisément les besoins.
Si tu n'as pas de table "resultat" il te faut une table "x" qui coordonnera en quelque sorte les autres. Cette table devrait avoir deux colonnes : champs1 (clé primaire) et nb, où "nb" représente le nombre de table où "champs1" est présent. À chaque nouvelle insertion/suppression dans une des autres tables, tu insères un nouvel enregistrement dans "x" ou mets à jour l'enregistrement correspondant. Tu peux le faire dans ton application ou, si tu es sûr d'utiliser MySQL 5, par des procédures stockées.
Dans ton application, tu sauras probablement à l'avance si un enregistrement existe, ce qui te permettra de choisir un INSERT ou UPDATE, mais si ce n'est pas le cas tu peux toujours faire un INSERT IGNORE avec "nb" à 0 suivi d'un UPDATE pour l'augmenter, ou faire les deux en même temps avec ON DUPLICATE KEY
Code : Tout sélectionner
INSERT INTO x VALUES ('ABC', 1) ON DUPLICATE KEY UPDATE nb = nb + 1
En procédures stockées, sauf erreur
Code : Tout sélectionner
DELIMITER //
CREATE TRIGGER ai_table1 AFTER INSERT ON table1
FOR EACH ROW
BEGIN
INSERT INTO x VALUES (NEW.champs1, 1) ON DUPLICATE KEY UPDATE nb = nb + 1;
END
//
CREATE TRIGGER ad_table1 AFTER DELETE ON table1
FOR EACH ROW
BEGIN
DECLARE $nb INT;
SELECT nb
INTO $nb
FROM x
WHERE champs1 = OLD.champs1;
IF ($nb > 1)
THEN
UPDATE x SET nb = nb - 1 WHERE champs1 = OLD.champs1;
ELSE
DELETE FROM x WHERE champs1 = OLD.champs1;
END IF;
END
//
CREATE TRIGGER ai_table2 AFTER INSERT ON table2
FOR EACH ROW
BEGIN
INSERT INTO x VALUES (NEW.champs1, 1) ON DUPLICATE KEY UPDATE nb = nb + 1;
END
//
CREATE TRIGGER ad_table2 AFTER DELETE ON table2
FOR EACH ROW
BEGIN
DECLARE $nb INT;
SELECT nb
INTO $nb
FROM x
WHERE champs1 = OLD.champs1;
IF ($nb > 1)
THEN
UPDATE x SET nb = nb - 1 WHERE champs1 = OLD.champs1;
ELSE
DELETE FROM x WHERE champs1 = OLD.champs1;
END IF;
END
//
CREATE TRIGGER ai_table3 AFTER INSERT ON table3
FOR EACH ROW
BEGIN
INSERT INTO x VALUES (NEW.champs1, 1) ON DUPLICATE KEY UPDATE nb = nb + 1;
END
//
CREATE TRIGGER ad_table3 AFTER DELETE ON table3
FOR EACH ROW
BEGIN
DECLARE $nb INT;
SELECT nb
INTO $nb
FROM x
WHERE champs1 = OLD.champs1;
IF ($nb > 1)
THEN
UPDATE x SET nb = nb - 1 WHERE champs1 = OLD.champs1;
ELSE
DELETE FROM x WHERE champs1 = OLD.champs1;
END IF;
END
//
DELIMITER ;
Avec une colonne "nb", rien de plus facile que de faire un ORDER BY nb DESC. Tu pourrais le faire dynamiquement, avec une grosse requête avec des jointures et des UNION, mais ce serait inefficace et finalement plus compliqué.