MySQL SUM Frage
berlinsurfer
- datenbank
Liebe Experten,
heute mal eine Frage zu MySQL SUM: Irgendwie stehe ich gerade auf dem Schlauch, ist es möglich zwei Variablen innerhalb eines Querys zu addieren ?
Folgenden Query habe, der die Dateigröße eines Artikels und evtl. "includierter" Artikel abfragt:
SELECT node.id as nodeid, article.*,
(SELECT SUM(filesize) FROM #__jpay_files files WHERE files.articleid = article.id) as filesize,
(SELECT SUM(includedfiles.filesize)
FROM #__jpay_articles_hierarchy fnode
JOIN #__jpay_included fincluded ON fnode.articleid = fincluded.articleid
JOIN #__jpay_files includedfiles ON fincluded.includedid = includedfiles.articleid
WHERE fnode.id = $article
) as includedfilesize
FROM #__jpay_articles_hierarchy node
JOIN #__jpay_articles_descriptions article ON node.articleid = article.id
WHERE node.articleid = article.id AND node.id = $article
Ich möchte nun filesize + includedfilesize als eine Angabe haben (das ginge natürlich auch per php, mich würde aber die Vorgehensweise interessieren).
Wenn jemand alternativ eine bessere Möglichkeit aufzeigen kann, die Werte in einem Subquery zu addieren, wäre ich auch dankbar.
Gruß aus Berlin.
Jan
Hi berlinsurfer!
Ich möchte nun filesize + includedfilesize als eine Angabe haben (das ginge natürlich auch per php, mich würde aber die Vorgehensweise interessieren).
Du stehst grad echt auf dem Schlauch, was? =)
Auch MySQL kennt die einfache Addition mit dem +-Operator.
MfG H☼psel
Hallo, H☼psel,
Du stehst grad echt auf dem Schlauch, was? =)
ja, vielleict ist es Zeit für einen Kaffee... einfach als SELECT (filesize+includedfilesize) as summe
?
Gruß,
Jan
Ok, es ist wirklich Zeit für einen Kaffee. Ich musste einfach die beiden Subqueries addieren, dann ging es natürlich. Hmm, ich rieche den Duft schon...
Hi berlinsurfer!
Du stehst grad echt auf dem Schlauch, was? =)
ja, vielleict ist es Zeit für einen Kaffee... einfach alsSELECT (filesize+includedfilesize) as summe
?
Leider nicht. MySQL erlaubt die sofortige Weiterverwendung von Aliassen in der Selectliste nicht. Du musst die Berechnung noch einmal durchführen lassen oder darauf verzichten und erst in PHP addieren.
Mich erstaunt bloß, warum MySQL eine entsprechende Abfrage mit identischen Subselects nicht optimiert. Ein erster Versuch ergab eine verdoppelte Ausführungszeit von
SELECT (
SELECT SUM(id)
FROM t1
) AS s1, (
SELECT SUM(id)
FROM t2
) AS s2, (
(
SELECT SUM(id)
FROM t1
) + (
SELECT SUM(id)
FROM t2 )
) AS summe
gegenüber
SELECT (
SELECT SUM(id)
FROM t1
) AS s1, (
SELECT SUM(id)
FROM t2
) AS s2
MfG H☼psel
Hi,
Mich erstaunt bloß, warum MySQL eine entsprechende Abfrage mit identischen Subselects nicht optimiert.
Ich denke, dass ist auch eigentlich genau das, was ich fragen wollte. Ist es möglich, die Abfrage anders zu gestalten, so dass ich nur einen Subquery brauche ? Die Tabellen sehen so aus:
included:
id|articleid|includedid
files:
id|articleid|filesize
Was ich gerne hätte (und was eventuell aus dem oben ersichtlichen Query nicht ganz hervorgeht) ist die Anzeige der Dateigröße. Diese kann sich zusammensetzen aus einem einzelnen Artikel (Möglichkeit a.) oder einem Artikel, der mehrere Artikel enthält (z. B. eine Iconbox mit 10 Icons).
Verknüpft werden diese über die Tabelle included.
Danke & Gruß,
Jan
Hallo,
Leider nicht. MySQL erlaubt die sofortige Weiterverwendung von Aliassen in der Selectliste nicht.
Nicht nur MySQL. Das ist völlig normal.
Du musst die Berechnung noch einmal durchführen lassen oder darauf verzichten und erst in PHP addieren.
Nein, das ist nicht unbedingt erforderlich. Berechnung im inneren Subselect. Dieses erhält einen Namen, auf den man in der äußeren Abfrage zugreifen kann.
Beispiele:
</archiv/2010/4/t197229/#m1322687>
</archiv/2008/8/t175461/#m1153411>
Für sinnvolles Helfen wären Beispieldaten in Beispieltabellen mit dem gewünschten Ergebnis und der Begründung für das Ergebnis wünschenswert.
Zum mehrfachen Ausführen gleicher Subselects:
Andere DBMS wie PostgreSQL oder MS SQL-Server kennen für so etwas eine WITH-Klausel für das SELECT-Statement.
Freundliche Grüße
Vinzenz
Hallo Vinzenz,
danke für deine Antwort(en).
Nicht nur MySQL. Das ist völlig normal.
Schade, Berechnungen mit Aliasen wären recht sinnvoll meiner Ansicht nach.
Beispiele:
</archiv/2010/4/t197229/#m1322687>
</archiv/2008/8/t175461/#m1153411>
Schaue ich mir an, danke.
Für sinnvolles Helfen wären Beispieldaten in Beispieltabellen mit dem gewünschten Ergebnis und der Begründung für das Ergebnis wünschenswert.
Kein Problem:
1. Tabelle jos_jpay_articles_hierarchy:
id|articleid
145|146
2. Tabelle jos_jpay_articles_descriptions:
id|title|desc
146|Eine erste Komponente|Hier stehen ein paar Infos zu der Komponente.
3. Tabelle jos_jpay_articles_files:
id|articleid|file|filesize
197|146|03a_27_04_09.pdf|1799381
200|148|Koala.jpg|787360
198|146|02b_20_04_09.pdf|555915
199|147|Chrysanthemum.jpg|885640
4. Tabelle jos_jpay_included:
id|articleid|includedid
27|146|147
26|146|148
Jetzt gibt es zwei Möglichkeiten, nämlich einen Artikel ohne und mit anderen (quasi "includierten") Artikeln. Es geht mir um die Dateigröße, die ich für einen Artikel ohne andere Artikel bestimme über:
SELECT SUM(files.filesize)
FROM jos_jpay_articles_hierarchy node
JOIN jos_jpay_files files ON node.articleid = files.articleid
WHERE node.id = 144
Das wäre in diesem Beispiel 1799381 + 555915 = 2355296 (ca. 2,3 MB). Jetzt enthält der Artikel mit der ID 146 aber auch die Artikel 147 + 148, also zusätzlich die Größen 787360 + 885640 = 1673000. Insgesamt müsste also 4028296 herauskommen. Wie erreiche ich das ?
Vielen lieben Dank für die Bemühungen,
Jan
Edit:
SELECT SUM(files.filesize)
FROM jos_jpay_articles_hierarchy node
JOIN jos_jpay_files files ON node.articleid = files.articleid
WHERE node.id = 145 (nat. 145)
Auf die Gefahr hin, mein Alleinunterhalter zu sein, hier meine Lösung (durch einfaches Umstellen):
SELECT SUM(files.filesize)
FROM jos_jpay_articles_hierarchy node
JOIN jos_jpay_files files ON node.articleid = files.articleid
WHERE node.id = 145 AND files.articleid = node.articleid OR files.articleid IN
(SELECT included.includedid
FROM jos_jpay_articles_hierarchy inode
JOIN jos_jpay_included included ON inode.articleid = included.articleid
WHERE inode.id = 145)
Dies ergibt die korrekte Summe von 4028296 und funktioniert auch, wenn keine Dateien inkludiert werden. Ich denke, ein Subquery ist geschwindigkeitstechnisch völlig vertretbar, oder ?
Vielen Dank an alle Helfenden !