Join: einzelne + korrespondierende Einträge zweier Tabellen
gk
- datenbank
Hallo,
folgende Situation
Tabelle 1:
name1 wert
a x
a y
a z
b k
c r
c s
Tabelle 2:
name2 anzahl
a 1
b 7
d 3
Das Problem ist nun, mit einer einzigen Abfrage eine liste zu erstellen, in der alle Namen auftauchen und die Anzahl so bestimmt wird, indem die einträge in der ersten Tabelle gezählt werden und die Anzahl aus der zweiten dazuaddiert wird.
gewünschtes Resultat:
name gesamtzahl
a 4
b 8
c 2
d 3
Wenn ich für die Abfrage einen Join mit der Bedingung name1=name2 einsetze erhalte ich natürlich nur diejenigen Namen, die in beiden gleichzeitig vorhanden sind.
Meine Frage: Ist es überhaupt möglich, mit einem _einzigen_ Select (ohne Subselects) aus diesen zwei Tabellen die Vereinigungsmenge und nicht nur den Durchschnitt erhalte?
Für Hilfe und Anregung wäre ich sehr dankbar.
vg,
gk
Das Problem ist nun, mit einer einzigen Abfrage eine liste zu erstellen, in der alle Namen auftauchen und die Anzahl so bestimmt wird, indem die einträge in der ersten Tabelle gezählt werden und die Anzahl aus der zweiten dazuaddiert wird.
ein bischen merkwürdig was du da wiilst.
aber die anzahl der tabelle 1 bekommst du mit COUNT.
wenn die tabelle 2 auch duplikate enthält muß SUM ran.
ein join versteht sich von selbst.
in etwa:
select (count(tabellle.name1)+sum(tabelle2.anzahl)) as gesamtzahl
from tabelle1 join tabelle2 on tabelle1.name1 = tabelle2.name2
ein bischen merkwürdig was du da wiilst.
aber die anzahl der tabelle 1 bekommst du mit COUNT.
wenn die tabelle 2 auch duplikate enthält muß SUM ran.
ein join versteht sich von selbst.
in etwa:
select (count(tabellle.name1)+sum(tabelle2.anzahl)) as gesamtzahl
from tabelle1 join tabelle2 on tabelle1.name1 = tabelle2.name2
ja, aber damit erhält man, wie im Originalposting beschrieben, nur die Namen, die in beiden Tabellen gleichzeitig sind.
im Beispiel also nur
name gesamtzahl
a 4
b 8
troztdem vielen dank
gk
ein bischen merkwürdig was du da wiilst.
zwar merkwürdig, aber für meine Belange wäre es praktisch.
Tabelle 1 wäre z.B. eine Besucherstatistik des aktuellen Monats, wo beispielsweise die Namen der besuchten Seiten stehen sowie die IP-Adressen.
In Tabelle 2 steht z.B. die Besucherstatistik von Anfang an bis zum Vormonat in der Form Name der Seite und Anzahl der Besuche.
Um die Gesamtstatistik zu erhalten, sollten nun die Seitenbesuche in der aktuellen Tabelle gezählt werden und dazu die Werte aus der zweiten Tabelle addiert werden.
Für Seiten, die sowohl früher, als auch aktuell besucht wurden, klappt das auch. Das Problem ist nun, auch Seiten anzuzeigen, die im aktuellen Monat noch nicht aufgerufen wurden bzw. Seiten, die zum erstenmal im aktuellen Monat aufgerufen wurden und deshalb noch nicht im "Archiv" Tabelle 2 sind.
Mit zwei Selects wäre das kein Problem, aber ich hätte es gerne mit einem Select, und zwar aus zwei Gründen:
Gruß,
gk
ja, aber damit erhält man, wie im Originalposting beschrieben, nur die Namen, die in beiden Tabellen gleichzeitig sind.
versuchs mal mit nem outer-join
Hallo gk!
Du benötigst zwei SQL-Abfragen:
1. SQL-Abfrage:
CREATE TEMPORARY TABLE tmp_tbl
SELECT Tabelle_1.Name1 AS 'Name', COUNT(*) AS 'Anzahl'
FROM Tabelle_1;
2. SQL-Abfrage
SELECT (tmp_tbl.Anzahl+Tabelle_2.gesamtzahl)
FROM Tabelle_2, tmp_tbl
WHERE Tabelle_2.name = tmp_tbl.Name;
PS.: Wie immer -- ohne Gewähr!
yo,
das problem der beiden tabellen ist, dass nicht in einer der beiden tabelle immer mindestens ein eintrag des jeweiligen namen drinne steht. wäre dies der fall, könnte man mit einem outer join und group by über den namen arbeiten. ansonsten hilft nur mengenoperatoren einsetzten und das ist stark von der version und dem jeweiligen dbms abhängig.
Ilja
bei einem outer join werden beide tabellen komplett gemäß den bedingungen gelesen.
enthält eine der beiden tabellen keinen eintrag gemäß der verknüpfung, wird ein NULL generiert.
somit ergibt sich eine 'vereinigungsmenge', welche alle sätze enthält, welche entweder in einer der beiden tabellen oder in beiden enthalten ist.
also: erst mal lesen, dann andere durcheinander bringen.
yo,
somit ergibt sich eine 'vereinigungsmenge', welche alle sätze enthält, welche entweder in einer der beiden tabellen oder in beiden enthalten ist.
also: erst mal lesen, dann andere durcheinander bringen.
nun des lesens bin ich mächtig. das verstehen ist sicherlich ein wackliges boot, das besonders bei mir manchmal durch ein leckeres bier getrübt wird.
so weit mir bekannt führt ein outer join dazu, dass alle datensätze --> einer <-- tabelle genommen werden und mit den datensätzen der anderen tabelle gemäß der join anweisung verknüpft werden. ist keiner entsprechender datensatz in der zweiten tabelle vorhanden, wird der datensatz der ersten tabelle trotzdem in die ergebnistabelle übernommen (outer join) und die fehlende werte der zweiten tabelle mit NULL aufgefüllt. die betonung liegt hier, dass nur bei --> einer <-- tabelle und nicht auf beiden tabellen alle datensätze genommen werden.
das wiederum führt dazu, dass zumindestens in einer tabelle alle namen mindestens einmal vorhanden sein sollten, um sie als "treibende" tabelle nehmen zu können. ansonsten werden die fehlenden namen der treibenden tabelle nicht in der ergebnisliste erscheinen, auch nicht, wenn sie in der zweiten tabelle vorhanden sein sollten.
sicherlich ist es möglich, dass ich mich dies bezüglich irre. dann würde ich dich bitten, das auch zu belegen.
Ilja
so weit mir bekannt führt ein outer join dazu, dass alle datensätze --> einer <-- tabelle genommen werden und mit den datensätzen der anderen tabelle gemäß der join anweisung verknüpft werden. ist keiner entsprechender datensatz in der zweiten tabelle vorhanden, wird der datensatz der ersten tabelle trotzdem in die ergebnistabelle übernommen (outer join) und die fehlende werte der zweiten tabelle mit NULL aufgefüllt. die betonung liegt hier, dass nur bei --> einer <-- tabelle und nicht auf beiden tabellen alle datensätze genommen werden.
bei left oder right outer wird nur die linke oder rechte (EINE) tabelle komplett gelesen.
das wiederum führt dazu, dass zumindestens in einer tabelle alle namen mindestens einmal vorhanden sein sollten, um sie als "treibende" tabelle nehmen zu können. ansonsten werden die fehlenden namen der treibenden tabelle nicht in der ergebnisliste erscheinen, auch nicht, wenn sie in der zweiten tabelle vorhanden sein sollten.
beim outer join oder full outer join werden BEIDE tabellen komplett gelesen.
yo,
beim outer join oder full outer join werden BEIDE tabellen komplett gelesen.
das stimmt, nur ist ein outer join nicht automatisch ein full outer join und zweitens steht diese funktionalität nicht immer zur verfügung. wenn mich nicht alles täuscht, kennt mysql diesen gar nicht. ein weiterer nachteil bei dieser lösung wäre, dass man zwar damit alle namen bekommen würde, aber eben in unterschiedlichen spalten.
Ilja