MySQL SUM bilden

resoucer

Gesperrt
ID: 77379
L
20 April 2006
2.846
109
Hallo,

undzwar kommt ich gerade nicht weiter. Mir fehlt ein Gedankenstoß wie ich das genau umsetzen soll.

1 Tabelle
ID 1 / Betrag = 100
ID 2 / Betrag = 200
ID 3 / Betrag = -10

2 Tabelle
ID 1 / Betrag = 20 / TAB1_ID = 1
ID 2 / Betrag = 200 / TAB1_ID = 2

Jetzt möchte ich alle aus Tabelle 1 haben wo noch ein Betrag über ist, also nicht 0.

Also Ergebnis sollte jetzt raus kommen
ID 1 / Betrag 80
ID 2 / Betrag -10

Könnt Ihr mir sagen wie die dazugehörigen SQL lautet??

Danke schonmal
 
stehen die Tabellen in einer 1:1 Beziehung, oder kann eine ID der Tabelle 1 öfters in TAB1_ID von Tabelle 2 auftauchen ?
Wäre also z.B. sowas möglich:

2 Tabelle
ID 1 / Betrag = 20 / TAB1_ID = 1
ID 2 / Betrag = 200 / TAB1_ID = 2
ID 3 / Betrag = 100 / TAB1_ID = 2
 
stehen die Tabellen in einer 1:1 Beziehung, oder kann eine ID der Tabelle 1 öfters in TAB1_ID von Tabelle 2 auftauchen ?
Wäre also z.B. sowas möglich:

2 Tabelle
ID 1 / Betrag = 20 / TAB1_ID = 1
ID 2 / Betrag = 200 / TAB1_ID = 2
ID 3 / Betrag = 100 / TAB1_ID = 2

nicht direkt was du schreibst. Das hier ist aber möglich

2 Tabelle
ID 1 / Betrag = 20 / TAB1_ID = 1
ID 2 / Betrag = 50 / TAB1_ID = 2
ID 3 / Betrag = 50 / TAB1_ID = 2
ID 4 / Betrag = 50 / TAB1_ID = 2
ID 5 / Betrag = 50 / TAB1_ID = 2
[/QUOTE]

In Tabelle 1 steht der Max. Betrag und in der 2 Tabelle stehen die Teilbeträge. Ich möchte jetzt halt alles raus haben wo noch nicht auf 0 reduziert wurde.
 
Im Prinzip könnte man es über einen UNION ALL lösen, aber ich weiss nicht, ob MySQL das inzwischen kann:


Code:
SELECT  ID , SUM(BETRAG) AS RESTBETRAG
FROM 
( SELECT ID , BETRAG FROM Tabelle1
UNION ALL
  SELECT TAB1_ID , -1*BETRAG AS BETRAG FROM Tabelle2 ) x
GROUP BY ID
HAVING SUM(BETRAG) > 0

oder ein LEFT JOIN

Code:
SELECT 
ID , T1.BETRAG - IFNULL(T2.BETRAG , 0 )
FROM Tabelle1 T1 
LEFT JOIN
( SELECT SUM(BETRAG) BETRAG , TAB1_ID  
FROM Tabelle2
GROUP BY TAB1_ID ) T2
ON T1.ID = T2.TAB1_ID
WHERE T1.BETRAG IS DISTINCT FROM T2.BETRAG
 
also beim left join scheint ein fehler zu sein

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NULL (T2.BETRAG , 0 )

das andere teste ich gerade mal

also das geht

Code:
SELECT  ID , SUM(BETRAG) AS RESTBETRAG
FROM 
( SELECT ID , BETRAG FROM Tabelle1
UNION ALL
  SELECT TAB1_ID , -1*BETRAG AS BETRAG FROM Tabelle2 ) x
GROUP BY ID
HAVING SUM(BETRAG) > 0
musste nur >0 in !=0 umwandeln.

Da ich ja auch alle - Beträge haben muss

Danke!!
 
Zuletzt bearbeitet:
Ich hätte da auch noch etwas schönes:

PHP:
SELECT test1.id, IFNULL(test1.value - SUM(test2.value), test2.value) AS ergebnis
FROM test1
LEFT OUTER JOIN test2
ON test1.id = test2.id
GROUP BY test2.id
HAVING ergebnis <> 0
ORDER BY test1.id

Liefert bei Eingangsdaten:
Tabelle 1:
id value
1 100
2 200
3 -10

Tabelle 2
id value
1 20
2 50
2 50
2 50
2 50

als Ergebnis:
1: 80
3: -10
 
Ich hätte da auch noch etwas schönes:

PHP:
SELECT test1.id, IFNULL(test1.value - SUM(test2.value), test2.value) AS ergebnis
FROM test1
LEFT OUTER JOIN test2
ON test1.id = test2.id
GROUP BY test2.id
HAVING ergebnis <> 0
ORDER BY test1.id

ich habs vesucht mit folgenden Daten

Tabelle 1
ID 1 / Betrag 68.99
ID 21 / Betrag - 10

Tabelle 2
ID 1 / Betrag 20 / ZU_ID 1
ID 2 / Betrag 10 / ZU_ID 1
ID 3 / Betrag -2 / ZU_ID 21

Als Ergebnis kommt
ID 1 / Betrag 48.99

also das passt irgendwas nicht. Evtl muss ich noch dabei sagen Bei minus Beträgen muss so gerechnet werden.

Tabelle 1
-10
Tabelle 2
- 2

Ergebnis -8
Hoffe das kann man verstehen
 
ich habe das value datenformat auf double, und mit den Daten:
Tabelle 1
ID 1 / Betrag 68.99
ID 2 / Betrag - 10

Tabelle 2
ID 1 / Betrag 20 / ZU_ID 1
ID 2 / Betrag 10 / ZU_ID 1
ID 3 / Betrag -2 / ZU_ID 2

kommt bei mir als Ergebnis:

1: 38.989999999999995
2: -8
 
Zuletzt bearbeitet:
Jetzt weiss ich wo der Haken ist:
Deine Tabelle 2 verwendet zusätzlich eine eigene ID-Spalte (z. B. als laufende Nr.), also 3 Spalten.
Nötig für die Berechnung sind aber nur 2, nämlich "id" (die auf die id in Tabelle 1 verweist) und "value" mit dem Wert, der dazu gehört.
Daher sind Tabellen-Layouts eigentlich auch sehr hilfreich, um solche Missverständnisse zu vermeiden.
 
ich habe das value datenformat auf double, und mit den Daten:
Tabelle 1
ID 1 / Betrag 68.99
ID 2 / Betrag - 10

Tabelle 2
ID 1 / Betrag 20 / ZU_ID 1
ID 2 / Betrag 10 / ZU_ID 1
ID 3 / Betrag -2 / ZU_ID 2

kommt bei mir als Ergebnis:

1: 38.989999999999995
2: -8

mhh komisch. Habe ich auch.
Habs mal mit

Tabelle 1
ID 1 / Betrag 68.99
ID 2 / Betrag - 10

Tabelle 2
ID 1 / Betrag 58.99 / ZU_ID 1

Versucht. Da kommt dann nur 1 Treffer mit
10 raus. Aber der mit -10 fehlt ja noch
 
Tippfehlerteufel beim Übertragen!

korrekt ist:
PHP:
SELECT test1.id, IFNULL(test1.value - SUM(test2.value), test1.value) AS ergebnis
FROM test1
LEFT OUTER JOIN test2
ON test1.id = test2.id
GROUP BY test2.id
HAVING ergebnis <> 0
ORDER BY test1.id

So, nun aber :)

Und als Hilfe die CREATEs:
CREATE TABLE test1 (
id double,
value double
)ENGINE=MyISAM;

CREATE TABLE test2 (
id double COMMENT 'bezieht sich auf Tabelle test1',
value double
)ENGINE=MyISAM;
 
Tippfehlerteufel beim Übertragen!

korrekt ist:
PHP:
SELECT test1.id, IFNULL(test1.value - SUM(test2.value), test1.value) AS ergebnis
FROM test1
LEFT OUTER JOIN test2
ON test1.id = test2.id
GROUP BY test2.id
HAVING ergebnis <> 0
ORDER BY test1.id

So, nun aber :)

Und als Hilfe die CREATEs:
CREATE TABLE test1 (
id double,
value double
)ENGINE=MyISAM;

CREATE TABLE test2 (
id double COMMENT 'bezieht sich auf Tabelle test1',
value double
)ENGINE=MyISAM;

was ist denn wenn ich die ID brauche um einzelne Datensätze löschen zu können? Ich brauche dort eine eindeutige ID in der Tabelle
 
Das liesse sich z. B. so realisieren, wodurch jeder Datensatz jeder Tabelle über die eindeutige ID angesprochen werden kann:

CREATE TABLE test1 (
eindeutige_id_1 int unsigned auto_increment primary key,
id double,
value double
)ENGINE=MyISAM;

CREATE TABLE test2 (
eindeutige_id_2 int unsigned auto_increment primary key,
id double COMMENT 'bezieht sich auf Tabelle test1',
value double
)ENGINE=MyISAM;


edit:
und in Tabelle test1 kann die eindeutige_id-Spalte wegfallen, falls jede id nur genau 1x vorkommt.
 
Etwas umgebaut (da nicht alles erforderliche ausgegeben wurde), und jetzt mal als Komplettpaket:

Alte Tabellen löschen:
PHP:
mysql_query("DROP TABLE IF EXISTS `test1`");
mysql_query("DROP TABLE IF EXISTS `test2`");

Tabellen erstellen:
PHP:
mysql_query("CREATE TABLE IF NOT EXISTS `test1`
(
 `eindeutige_id_1` int unsigned auto_increment primary key,
 `id`     int unsigned,
 `value`  decimal(10,2) DEFAULT 0
)ENGINE=MyISAM;")or die(mysql_error());

mysql_query("CREATE TABLE IF NOT EXISTS `test2`
(
 `eindeutige_id_2` int unsigned auto_increment primary key,
 `id`     int unsigned COMMENT 'verweist auf Spalte: Tabelle1.id',
 `value`  decimal(10,2) DEFAULT 0
)ENGINE=MyISAM;")or die(mysql_error());

Daten einfügen:
PHP:
mysql_query("INSERT INTO test1 (id,value) VALUES(1,68.99),(2,-10),(3,310),(4,410),(5,510),(6,610)");
mysql_query("INSERT INTO test2 (id,value) VALUES(3,300),(3,10),(4,10),(4,20),(4,15)");

Die eigentliche Abfrage:
PHP:
$e1=mysql_query("SELECT DISTINCT test1.id AS id1, IFNULL(test1.value - (SELECT SUM(value) FROM test2 WHERE id=id1), test1.value) AS ergebnis
 FROM                test1
 LEFT OUTER JOIN     test2
 ON                  test1.id = test2.id
 HAVING              ergebnis <> 0
 ORDER BY            test1.id")or die(mysql_error());
WHILE($z1=mysql_fetch_row($e1))
{
 echo "$z1[0]: $z1[1]<br>";
}

Die Ausgabe:
1: 68.99
2: -10.00
4: 365.00
5: 510.00
6: 610.00
 
Zuletzt bearbeitet: