2009-07-12 5 views
1

Dans une suite à une question précédente, disons que j'ai 3 tables, A, B et C. Le tableau A a un ID qui est utilisé comme clé étrangère dans les tables B et C, dont chacun a une certaine valeur en tant qu'attribut. Pour chaque ID dans le tableau A, je veux obtenir la différence de valeur entre les tables B et C, qui peut être fait comme suit:Vues en MySQL basées sur plusieurs valeurs calculées

CREATE VIEW T1 AS 
    SELECT B.A_ID AS ID, SUM(B.VALUE) AS VAL 
    FROM B 
    GROUP BY B.A_ID; 
CREATE VIEW T2 AS 
    SELECT C.A_ID AS ID, SUM(C.VALUE) AS VAL 
    FROM C 
    GROUP BY C.A_ID; 
SELECT T1.ID, T1.VAL, T2.VAL FROM T1, T2 WHERE T1.ID = T2.ID; 

Le problème est, si le tableau B a des valeurs pour un ID particulier , mais pas la table C, ou vice versa. Dans ce cas, mon instruction select ne retournera pas cette ligne. Est-il possible pour moi de créer une vue unique, qui ressemble essentiellement comme suit:

CREATE VIEW T3 AS 
    SELECT B.A_ID AS ID, SUM(B.VALUE) AS VAL1, SUB(C.VAL) AS VAL2 
    FROM B, C 
    WHERE B.A_ID = C.A_ID 
    GROUP BY B.A_ID; 

Un exemple du script de création d'un tel point de vue serait apprécié.

+0

Je suis vraiment intéressé par la solution qui a fini par fonctionner pour vous. –

+0

Je vais probablement essayer, au moins, en utilisant celui que vous avez proposé. J'ai un problème avec mon fournisseur d'hébergement avec mon accès utilisateur aux bases de données en cours de résolution, donc je n'ai pas encore pu le tester, même si j'ai mes scripts préparés. Si votre solution fonctionne, j'accepterai votre réponse comme correcte. – Elie

+0

Il s'avère que mon fournisseur d'hébergement ne supporte que MySQL 5.0, et les vues ont été introduites dans MySQL 5.0.1, donc cette option pour assembler les données automatiquement est sortie. – Elie

Répondre

1

Vous pouvez utiliser ce

CREATE VIEW myView AS 
SELECT test_a.id, name, IFNULL((
    SELECT SUM(value) 
    FROM test_b 
    WHERE test_b.a_id = test_a.id 
    GROUP BY test_b.a_id) , 0 
) - IFNULL((
    SELECT SUM(value) 
    FROM test_c 
    WHERE test_c.a_id = test_a.id 
    GROUP BY test_c.a_id) , 0 
) 
FROM test_a 

Mais cela se traduira par des nombres négatifs si c est une somme supérieure à b. Si vous voulez que la différence absolue que d'utiliser ceci:

CREATE VIEW myView AS 
SELECT test_a.id, name, ABS(IFNULL((
    SELECT SUM(value) 
    FROM test_b 
    WHERE test_b.a_id = test_a.id 
    GROUP BY test_b.a_id) , 0) - IFNULL((
SELECT SUM(value) 
    FROM test_c 
    WHERE test_c.a_id = test_a.id 
    GROUP BY test_c.a_id) , 0 
) 
) 
FROM test_a 
+0

Considérant que les deux tables B et C ont potentiellement des milliers de lignes, pour des centaines de lignes dans A, quelles seraient les performances de cette requête? (J'utiliserais la première option, car j'ai besoin de savoir si la différence est positive ou négative.) De plus, y a-t-il un moyen de le faire en tant que point de vue? – Elie

+0

pour créer une vue ajouter CREATE VIEW viewName AS devant la requête ... en ce qui concerne la performance je ne sais pas ... vous devrez l'essayer ... Je viens de mettre en place trois tables avec quelques lignes chacune. Un autre problème à considérer est s'il y a un ID dans la table a qui n'est pas dans b ou c ... mes requêtes retourneront 0. Si vous ne le voulez pas, il y a des façons de le contourner. –

0
SELECT ID, MAX(VAL1), MAX(VAL2) FROM 
((SELECT B.A_ID AS ID, SUM(B.VALUE) AS VAL1, 0 as VAL2 
FROM B GROUP BY B.A_ID) as T1 
UNION 
(SELECT C.A_ID AS ID, 0 VAL1, SUM(C.VALUE) AS VAL2 
FROM C GROUP BY C.A_ID) as T2) as Foo 
GROUP BY FOO.ID 

Son un peu aki. De plus, vous ne pouvez pas créer une vue qui a une union.

Questions connexes