Query an mehrere Tabellen
Bernd
- datenbank
0 Bernd0 Ilja0 Philipp Hasenfratz0 Bernd1 Ilja
Hi,
ich möchte aus drei Tabellen auslesen. Aus einer möchte ich allerdings nur wissen wieviele Reihen drin sind, die bei der Spalte id die selbe id haben wie die id in den anderen Tabellen.
Tabellen: x, y, z (beispiel)
Query:
SELECT x.id, x.name, x.datum, y.text, z.count(z.id) FROM
x, y, z
WHERE
x.id = y.id AND
x.id = z.id
ORDER BY
x.datum DESC
LIMIT
3;
x.id ist primary key
y,z.id ist kein primary key
Gruß
Bernd
Hi,
sorry bei dem Query war ein Fehler es sollte heißen:
SELECT x.id, x.name, x.datum, y.text, z.count(z.id) AS 'comments' FROM
x, y, z
WHERE
x.id = y.id AND
x.id = z.id
ORDER BY
x.datum DESC
LIMIT
3;x.id ist primary key
y,z.id ist kein primary keyGruß
Bernd
yo,
ich möchte aus drei Tabellen auslesen. Aus einer möchte ich allerdings nur wissen wieviele Reihen drin sind, die bei der Spalte id die selbe id haben wie die id in den anderen Tabellen.
das zählen (count) ist eine aggregat-funktion und leider ist deren anwendung nicht immer ganz einfach. in aller regel kommt es zu schwierigkeiten, wenn man zusätzliche nicht aggregat spalten mit angezeigt haben will. in aller regel gibt es hierfür die GROUP BY klausel, die sich aber nur bedinkt in deinem falle anwenden läßt.
lange rede kurzer sinn, ich würde dir in deinem falle zu zwei abfragen raten oder aber du benutzt unterabfragen. im letzteren fall stellt sich die frage, ob deine mysql version diese unterstützen.
Ilja
Hi,
die mysql-Version müsste was um 4.x sein.
Wie würde das denn mit einer Unterabfrage aussehen, habe nämlich keine Ahnung davon.
mfg Bernd
yo,
Wie würde das denn mit einer Unterabfrage aussehen, habe nämlich keine Ahnung davon.
das würde zum einen eine "ganz normale" abfrage sein + einer unterabfrage innerhalb der ausgabe der spalten. dies kostet aber ein wenig performance. musst einfach mal versuchen, ob sie so genommen wird, ansonsten hier fehlermeldungen und probleme posten....
SELECT x.id, x.name, x.datum, y.text,
(SELECT count(*) FROM z AS z2 WHERE z2.id = z.id) AS Anzahl
FROM x, y, z
WHERE x.id = y.id AND x.id = z.id
ORDER BY x.datum DESC
LIMIT 3;
Ilja
Halihallo Bernd
ich möchte aus drei Tabellen auslesen. Aus einer möchte ich allerdings nur wissen wieviele Reihen drin sind, die bei der Spalte id die selbe id haben wie die id in den anderen Tabellen.
Dann brauchst du typischerweise einen GROUP BY und COUNT()
x.id ist primary key
y,z.id ist kein primary key
Hier wirst du das Problem haben, dass auf ein x.id mehrere y-Records
und mehrere z-Records passend sind. Ein COUNT(*) würde dir bei einem
GROUP BY x.id also (AnzahlRecordsAusY * AnzahlRecordsAusZ) liefern und
das möchtest du nicht. Ein COUNT(DISTINCT z.id) würde dir bei einem
GROUP BY x.id zwar die richtige Anzahl z.id's liefern, jedoch kannst
du dann y.text nicht auslesen, da diese nicht Bestandteil der GROUP
BY Klausel ist (alle Attribute die du nicht in der GROUP BY stehen
hast, müssen mit Aggregatsfunktionen behandelt werden wie z.B. COUNT,
MIN, MAX, FIRST etc.). Falls y.id auch PRIMARY KEY wäre, hätte man
keine Probleme => GROUP BY x.id, y.id, y.text und COUNT(*) für die
Anzahl z-Records.
Wie steht denn y.text im Bezug auf x.id (also was ist die y und was
ist die x Relation?). Dies musst du und muss man wissen, um diese
Aufgabe sinnvoll zu lösen. Entweder ein x kann mehrere y-Tupel haben
(1:N), dann sagst du uns aber nicht, welches y.text du haben
möchtest, bzw. ob man nun alle z-Tupel in Relation zu x oder zu (x,y)
zählen soll.
Für eine Lösung brauchen wir mehr Input :-)
Viele Grüsse
Philipp
Hi,
die Tabellen stehen in inhaltlichen zusammenhang, z.B.:
id = 1
Die Wert aus Tabelle x und y mit der selben id gehören zusammen. Bei x und y sind die id einzigartig, es gibt nur eine Reihe mit der gleichen id. Aber bei Tabelle z gibt es mehrere Reihen mit der gleichen id.
Wofür das ganze?
In x und y will ich Blogs speichern und in z die Comments dazu. Mit dem Query soll also der Blog aus x und y ausgelesen werden und bei z gezählt werden wieviele Comments es dazu gibt.
mfg Bernd
Halihallo Bernd
Die Wert aus Tabelle x und y mit der selben id gehören zusammen. Bei x und y sind die id einzigartig, es gibt nur eine Reihe mit der gleichen id. Aber bei Tabelle z gibt es mehrere Reihen mit der gleichen id.
Aha, man kann also sagen, dass x.id der PRIMARY KEY von x ist und
y.id zumindest ein Schlüsselkandidat von y. Gut, das ist wichtig zu
wissen. Frage: warum ist y.id nicht auch ein PRIMARY KEY?
Wofür das ganze?
Wenn du mein erstes Posting erneut genau liest, wirst du verstehen,
warum das sehr wichtig ist. Um es nochmals zusammenzufassen: Wenn du
einen Join über drei Tabellen hast und diese in keiner 1:1 Beziehung
zueinander stehen, bekommst du beim Gruppieren nach einem Primary Key
und einem COUNT() das Produkt aus den zutreffenden Records aus y und
z. Weisst du jedoch, dass x.id=y.id und beide id's eindeutig sind und
in Beziehung stehen (1:1), liefert ein COUNT() die Anzahl treffender
Einträge aus z und *das* ist es, was du möchtest; vorangehend mussten
wir jedoch *wissen*, ob x und y in einer 1:1 Beziehung stehen.
In x und y will ich Blogs speichern und in z die Comments dazu. Mit dem Query soll also der Blog aus x und y ausgelesen werden und bei z gezählt werden wieviele Comments es dazu gibt.
Also:
SELECT
x.id, x.name, x.datum, y.text, COUNT(*) AS 'AnzahlKommentare'
FROM
x,y,z
WHERE
x.id=y.id AND
x.id=z.id
GROUP BY
x.id,x.name,x.datum,y.text
ORDER BY
x.datum DESC
LIMIT
3
Viele Grüsse
Philipp
yo holladiewaldfee Philipp,
x.id ist primary key
y,z.id ist kein primary keyHier wirst du das Problem haben, dass auf ein x.id mehrere y-Records
und mehrere z-Records passend sind.
nicht zwangsläufig, dass es kein pk ist schlisst nicht aus, dass es den constraint unique besitzt. aber grosser wahrscheinlichkeit wird es so sein, wie du schreibst.
Ein COUNT(*) würde dir bei einem
GROUP BY x.id also (AnzahlRecordsAusY * AnzahlRecordsAusZ) liefern und
das möchtest du nicht.
ein count(*) würde bei einem group by x.id meiner meinung nach nicht AnzahlRecordsAusY * AnzahlRecordsAusZ liefern.
Falls y.id auch PRIMARY KEY wäre, hätte man
keine Probleme => GROUP BY x.id, y.id, y.text und COUNT(*) für die
Anzahl z-Records.
auch das würde ich anders sehen. erstens hat das group by nichts mit pk's zu tun. und zweites würde diese konstellation des group by den falschen count liefern und somit zwangsweise falsche datensätze.
Ilja
Halihallo Ilja
x.id ist primary key
y,z.id ist kein primary keyHier wirst du das Problem haben, dass auf ein x.id mehrere y-Records
und mehrere z-Records passend sind.nicht zwangsläufig, dass es kein pk ist schlisst nicht aus, dass es den constraint unique besitzt. aber grosser wahrscheinlichkeit wird es so sein, wie du schreibst.
Jep, das ging bei meinen Überlegungen unter; wobei ich es eben als
Aufgabe des Fragestellers sehe uns dies mitzuteilen; ich habe
später noch gefragt, ob y.id nicht auch PRIMARY KEY (oder eben
besser: zumindest UNIQUE) ist.
Ein COUNT(*) würde dir bei einem
GROUP BY x.id also (AnzahlRecordsAusY * AnzahlRecordsAusZ) liefern und
das möchtest du nicht.ein count(*) würde bei einem group by x.id meiner meinung nach nicht AnzahlRecordsAusY * AnzahlRecordsAusZ liefern.
Jep, ebenfalls richtig wenn man davon ausgeht, dass die WHERE-Klausel
folgendes enthält: x.id=y.id AND x.id=z.id.
y.id=z.id ist dann implizit und bricht das Kreuzprodukt zwischen y
und z auf. Was am Ende bleibt ist COUNT(*)=Summe aus Y und Z-
Datensätzen, wenn dann noch x.id=y.id ist und y.id UNIQUE, ist
COUNT(*) die gewünschte Anzahl z-Records. Vorausgesetzt ich mache
jetzt nicht noch einen Überlegungsfehler :-)
Falls y.id auch PRIMARY KEY wäre, hätte man
keine Probleme => GROUP BY x.id, y.id, y.text und COUNT(*) für die
Anzahl z-Records.auch das würde ich anders sehen. erstens hat das group by nichts mit pk's zu tun.
Natürlich nicht, aber: Wenn sowohl der Primary Key von x und y im
GROUP BY auftaucht, wird nach jedem x und y Datensatz gruppiert und
der COUNT(*) liefert die Anzahl z-Records. Da x und y nach neuen
Erkenntnissen eine 1:1 Beziehung eingehen, wird der x und y Datensatz
zusammengezogen und so gruppiert, somit zählt COUNT(*) die Datensätze
in z. y.text steht nur in GROUP BY, dass man dieses Attribut ohne
Aggregatsfunktionen selektieren darf, hat jedoch keine Auswirkungen
auf die Gruppierung (da der PRIMARY KEY der Relation y enthalten
ist).
und zweites würde diese konstellation des group by den falschen count liefern und somit zwangsweise falsche datensätze.
Warum? - Weil ich auch noch nach y.text gruppiere? - Nein. Das ist
richtig, denn dieses y.text gruppiert nicht weiter, da bereits der
PRIMARY KEY von y im GROUP BY steht, somit ist eine Gruppierung nach
y.text bereits implizit (da ja jeder y Datensatz automatisch als
Gruppierungsglied herangezogen wird).
Viele Grüsse
Philipp
yo, guten morgen Philipp
Warum? - Weil ich auch noch nach y.text gruppiere?
unter anderem deshalb. es war ja zu dem zeitpunkt noch nicht klar, dass y.id ein PK/Unique ist, vielmehr hast du ihn zitiert, dass es keiner ist ?
Ilja
Halihallo und guten Nachmittag Ilja :-)
Warum? - Weil ich auch noch nach y.text gruppiere?
unter anderem deshalb. es war ja zu dem zeitpunkt noch nicht klar, dass y.id ein PK/Unique ist, vielmehr hast du ihn zitiert, dass es keiner ist ?
Zu dem Zeitpunkt war in der Tat noch nicht bekannt, dass es ein
PK/Unique ist, jedoch sagte ich folgendes:
Falls y.id auch PRIMARY KEY wäre, hätte man
keine Probleme => GROUP BY x.id, y.id, y.text und COUNT(*) für die
Anzahl z-Records.
Mit anderen Worten sagte ich, dass *wenn* y.id auch Primary Key ist
(oder eben besser: einfach Unique ist bzw noch besser: für jedes
x.id höchstens ein y.id gibt [es könnte auch NULL-Werte in y.id
vorkommen]); dann wäre der vorgeschlagene GROUP BY x.id, y.id, y.text
und COUNT(*) die richtige Lösung.
Falls y.id nicht unique ist (so habe ich angefangen), so hätte er
uns mitteilen müssen, welches y.text er wünscht, da bei einer nicht
1:1 Beziehung mehrere y.text für ein x.id geben kann und zudem nicht
bekannt ist, was er nun zu zählen wünscht (alle z Datensätze
bezüglich einer Gruppierung nach x oder nach (x,y)).
Ich hoffe, dass ich meine Gedanken verständlich ausgedrückt habe,
sonst frag doch bitte einfach nochmal :-)
Viele Grüsse
Philipp
yo mahlzeit,
Ich hoffe, dass ich meine Gedanken verständlich ausgedrückt habe,
sonst frag doch bitte einfach nochmal :-)
nein, du hast dich laut und deutlich ausgedrückt. und es ist richtig, sollte x.id, y.id und z.id PK/Unique sein, dann macht eine grupppierung über diese id's durch aus sinn und auch das einfügen zusätzlicher spalten wie text sollte dann kein problem sein. aber wie columbo habe ich nun doch noch eine frage. ;-)
wenn nun alle drei id's PK/Unique sind und man alle drei in die gruppierung mit rein nimmt, kommt dann nicht immer bei Count(*) ein möglicher wert raus, nämlich 1 bzw. im sonderfall 0 ? ist dann nicht der sinn des count(*) ausgehoben ?
Ilja
Halihallo Ilja
aber wie columbo habe ich nun doch noch eine frage. ;-)
Oha, ich fühle mich bereits schuldig :-) hoffentlich finde ich eine
super geniale Ausrede :-)
wenn nun alle drei id's PK/Unique sind und man alle drei in die gruppierung mit rein nimmt, kommt dann nicht immer bei Count(*) ein möglicher wert raus, nämlich 1 bzw. im sonderfall 0 ? ist dann nicht der sinn des count(*) ausgehoben ?
... jep, wenn alle beteiligten Join-Relationen mit PRIMARY KEY, oder
Schlüsselkandidat (UNIQUE) in GROUP BY aufgenommen werden, macht
jedwelcher COUNT(*) keinen Sinn, da er per Definition *immer* 1 ist.
0 kann übrigens bei COUNT(*) nicht vorkommen, 0 kann nur bei COUNT
(attr) oder COUNT(DISTINCT attr) vorkommen, nämlich dann, wenn attr
Tupelbedingt NULL ist bzw. durch einen OUTER JOIN mit NULL besetzt
wird.
Viele Grüsse
Philipp
yo,
... jep, wenn alle beteiligten Join-Relationen mit PRIMARY KEY, oder
Schlüsselkandidat (UNIQUE) in GROUP BY aufgenommen werden, macht
jedwelcher COUNT(*) keinen Sinn, da er per Definition *immer* 1 ist.
mit anderen worten, du setzt für das funktionieren deiner query vorraus, dass alle beteiligten die eigenschaft unique besitzen. aber genau diese eigenschaft setzt den sinn der count() funktion ausser kraft, nach der aber gefragt wurde. letztlich läuft es darauf hinaus, dass man vorsichtig sein muss, was man so in das group by mit rein nimmt, da es in aller regel einfluss auf die aggregat-funktionen hat. deshalb sehe ich bei diesem problem eher unterabfragen als mögliche lösung an. leider hat sich bernd nicht mehr gemeldet.....
0 kann übrigens bei COUNT(*) nicht vorkommen, 0 kann nur bei COUNT
(attr) oder COUNT(DISTINCT attr) vorkommen, nämlich dann, wenn attr
Tupelbedingt NULL ist bzw. durch einen OUTER JOIN mit NULL besetzt
wird.
jau das stimmt, 1 ist bei count() der kleinstmögliche wert, da immer eine ergebnistabelle erzeugt wird. da kann man mal sehen, auch columbo ist nicht perfekt ;-)
Ilja
Halihallo Ilja
... jep, wenn alle beteiligten Join-Relationen mit PRIMARY KEY, oder
Schlüsselkandidat (UNIQUE) in GROUP BY aufgenommen werden, macht
jedwelcher COUNT(*) keinen Sinn, da er per Definition *immer* 1 ist.mit anderen worten, du setzt für das funktionieren deiner query vorraus, dass alle beteiligten die eigenschaft unique besitzen.
Nein, ausschliesslich x.id und y.id; so dass auf jedes x-Tupel genau
(oder mindestens ein) y-Tupel zutrifft. Die z-Tupel stehen dann in
einer 1:N Beziehung zu wahlweise x.id oder y.id (was ja "dasselbe"
ist). Ein COUNT(*) zählt dann die z-Tupel, die zu id (x.id=y.id)
zugewiesen werden, also IMHO das, was Bernd erreichen wollte.
aber genau diese eigenschaft setzt den sinn der count() funktion ausser kraft, nach der aber gefragt wurde.
Dies wäre der Fall, wenn x.id=y.id=z.id zutrifft, wovon ich - nach
Bernds Aussagen - eben nicht ausgehe. x.id=y.id, aber z.id ist ein
Foreign Key und somit steht er in diesem Kontext in einer 1:N
Beziehung zu (x|y).id.
letztlich läuft es darauf hinaus, dass man vorsichtig sein muss, was man so in das group by mit rein nimmt, da es in aller regel einfluss auf die aggregat-funktionen hat. deshalb sehe ich bei diesem problem eher unterabfragen als mögliche lösung an. leider hat sich bernd nicht mehr gemeldet.....
Du hat eine korrelierte (d.h. für jedes Tupel der Main-Query, muss
die Unterabfrage erneut ausgewertet werden) Unterabfrage
vorgeschlagen, diese Kosten im Normalfall sehr viel, sollten also
(wenn es eine bessere Abfrage gibt) unterlassen werden. Falls jedoch
die GROUP BY-Lösung nicht funktionieren sollte (was Bernd
entscheiden muss), ist natürlich eine Unterabfrage unweigerlich die
richtige Lösung.
Soweit ich Bernds Problem verstanden habe, ist es jedoch mit GROUP BY
in diesem konkreten Fall einfach zu lösen.
Mal sehen, vielleicht meldet sich Bernd ja noch, wäre wirklich
hilfreich.
jau das stimmt, 1 ist bei count() der kleinstmögliche wert
Nur bei COUNT(*), nicht bei COUNT([DISTINCT] attr) :-)
da immer eine ergebnistabelle erzeugt wird. da kann man mal sehen, auch columbo ist nicht perfekt ;-)
Nein, nein, ich bin eben ein vielversprechender Halunke :-),
vielleicht Typus Professor Moriarty, das ist das Problem :-)
Viele Grüsse
Philipp
yo,
Nein, ausschliesslich x.id und y.id; so dass auf jedes x-Tupel genau
(oder mindestens ein) y-Tupel zutrifft. Die z-Tupel stehen dann in
einer 1:N Beziehung zu wahlweise x.id oder y.id (was ja "dasselbe"
ist). Ein COUNT(*) zählt dann die z-Tupel, die zu id (x.id=y.id)
zugewiesen werden, also IMHO das, was Bernd erreichen wollte.
dem muss/will ich zustimmen. wenn x.id und y.id PK sind und z.id kein PK, dann wird genau das gewünschte angezeigt. und das hast du auch die ganze zeit gesagt. da habe ich ein wenig zuviel in deine aussagen hinein interpretiert. insofern hast du recht. und group by ist sicherlich auch wesentlich schneller als unterabfragen, also in dem falle vorzuziehen.
auf der anderen seite, ist es fraglich, dass genau diese konstellation existiert, wenn auch nicht unmöglich. laut bernds aussagen ist nur x.id pk. insofern würde ich eher zu nein, bzw. da alle den namen id haben, eher zu allen drei als pk tendieren. wobei es sicherlich auch um FK handeln kann. who knows....
wobei mein 0 sonderfall mir wieder ins gedächnis gekommen ist. count(*) liefert immer einen wert, der aber im sonderfall auch 0 sein kann, nämlich wenn die ergebnis-tabelle leer ist.
Ilja
Halihallo Ilja
auf der anderen seite, ist es fraglich, dass genau diese konstellation existiert, wenn auch nicht unmöglich. laut bernds aussagen ist nur x.id pk. insofern würde ich eher zu nein, bzw. da alle den namen id haben, eher zu allen drei als pk tendieren. wobei es sicherlich auch um FK handeln kann. who knows....
Deswegen habe ich Bernd darauf angesprochen um selber sicher zu
gehen und er hat in https://forum.selfhtml.org/?t=94762&m=573809 geantwortet. Aus diesem
Posting lese ich, dass x.id und y.id unique sind und z.id hingegen
mehrfach vorkommt. Also genau diese Konstellation auf die ich mich
(seit dem Posting von Bernd) stets beziehe und mit GROUP BY lösbar
ist.
wobei mein 0 sonderfall mir wieder ins gedächnis gekommen ist. count(*) liefert immer einen wert, der aber im sonderfall auch 0 sein kann, nämlich wenn die ergebnis-tabelle leer ist.
Stopp mein geschätzter Columbo :-) Wenn ich mich kurz zittieren darf:
<cite>
wenn alle beteiligten Join-Relationen mit PRIMARY KEY, oder
Schlüsselkandidat (UNIQUE) in GROUP BY aufgenommen werden, macht
jedwelcher COUNT(*) keinen Sinn, da er per Definition *immer* 1 ist.
</cite>
Ich spreche von COUNT(*) nach einem GROUP BY. Es ist richtig, dass
bei einer leeren Ergebnisrelation COUNT(*) *ohne* GROUP BY beim
SELECT, 0 ausgibt. Aber bei einem GROUP BY ist die gesamte
Ergebnisrelation eine Empty-Set und es wird gar nix ausgegeben, also
auch kein COUNT(*)==0, sondern eben einfach ein Empty-Set. Sobald die
Ergebnisrelation nach einem GROUP BY eben kein Empty-Set ist, wirst
du nie COUNT(*) mit 0 antreffen, da Gruppierungen nach den Primary
Keys die keine Übereinstimmung finden gar nicht erst beim Join aus-
gegeben werden, somit nicht gruppiert werden und somit auch kein
COUNT(*)==0 auftreten kann.
Anders formuliert: Wenn du einen Join über zwei Relationen hast,
werden nur Tupel ausgegeben, die auf eine bestimmte Selektion
zutreffen; solche Tupel die nicht zutreffen (also keinen Join-Partner
in der anderen Relation finden => wo eben COUNT(*)==0 wäre), sind
gar nicht erst in der Ergebnisrelation bei welcher du GROUP BY
anwendest, somit wurde durch den JOIN schon jedwelche Möglichkeit ein
COUNT(*)==0 zu erreichen ausgeschlossen, da der JOIN nur aufgrund
der Selektion gültige Join-Partner zulässt und somit auch mindestens
ein Join-Partner in der anderen Relation haben. Eine Ausnahme bilden
hier die OUTER JOIN's, wo eben auch Join-Paare gebildet werden, wenn
auf der anderen Seite kein Partner gefunden wird, hier kann
COUNT(attr)==0 wirklich vorkommen, da aber COUNT(*) stupfsinnig die
Anzahl Tupel zählt, werden auch Tupel mit NULL-Werten gezählt.
Hm. Ich habe Probleme das irgendwie verständlich zu formulieren.
Zusammenfassend: Bei einem GROUP BY gibt ein COUNT(*) immer
mindestens eins aus, da sonst nach nix gruppiert geworden wäre und
das steht im Wiederspruch zur Definition was GROUP BY macht.
=> Paradoxon.
Viele Grüsse
Philipp
Halihallo
Noch eine kleine Zugabe: :-)
Hm. Ich habe Probleme das irgendwie verständlich zu formulieren.
Zusammenfassend: Bei einem GROUP BY gibt ein COUNT(*) immer
mindestens eins aus, da sonst nach nix gruppiert geworden wäre und
das steht im Wiederspruch zur Definition was GROUP BY macht.
=> Paradoxon.
Es sei denn, du argumentierst mit Attributfremden GROUP BY
Bedingungen:
SELECT COUNT(*) FROM a NATURAL JOIN b GROUP BY 1
Tja, wir haben einen GROUP BY und ein COUNT(*), sollte also nach
meiner Aussage kein COUNT(*)==0 vorkommen. Tut es aber, nämlich genau
dann, wenn bei 'a NAT.JOIN b' keine Entsprechungen gefunden werden,
dir also ein Empty Set zurückgegeben werden würde. Tja, das ist
nämlich genau dass, was ein "SELECT COUNT(*) FROM a" oder dem
Beispiel entsprechend ein "SELECT COUNT(*) FROM a NATURAL JOIN b"
machen würde.
Folge: Ich muss mich dahingegen korrigieren, dass ich von
Attributabhängigen GROUP BY Bedingungen spreche...
Viele Grüsse
Philipp
yo,
ich gestehe, die group by variante ist schneller und auch anwendbar, sprich das sollte bernd hoffentlich verwenden. was das group by 1 betrifft, so bekomme ich leider eine fehlermeldung dabei, kann aber an meinen dbms liegen, bzw. an der version. ich glaube, ich muss mir noch mal ein paar columbo filme ansehen....
Ilja
Halihallo Ilja
yo,
ich gestehe, die group by variante ist schneller und auch anwendbar, sprich das sollte bernd hoffentlich verwenden. was das group by 1 betrifft, so bekomme ich leider eine fehlermeldung dabei, kann aber an meinen dbms liegen, bzw. an der version.
Nun, es macht im Normalfall auch absolut keinen Sinn nach einer
Konstanten zu gruppieren, aber es war der Veranschaulichung dienlich.
Der Fehler kann bei MySQL daher rühren, dass Attribute intern einen
Alias erhalten und bei einem SELECT COUNT(*) das COUNT(*) intern 1
ist. Ein GROUP BY 1 (also GROUP BY COUNT(*)) führt dann logisch zu
einem Fehler. MySQL lässt sich jedoch auch austricksen:
SELECT COUNT(*) FROM table GROUP BY 1+1 /* welche Konstante man
wählt ist ja nebensächlich, das Ergebnis dasselbe. */
Dann wird 1 nicht mehr als internes Attributalias, sondern als Zahl
eines algebraischen Ausdrucks gewertet. Soweit zumindest meine
Vermutung und Schlüsse aus meiner Beobachtung.
ich glaube, ich muss mir noch mal ein paar columbo filme ansehen....
Und ich muss mich endlich mit schwarzer Magie auseinandersetzen :-)
Obwohl, dass was MySQL in diesem Zusammenhang macht, grenzt schon
fast an schwarze Magie (also ich meine meine Feststellungen von oben
bezüglich differenter und inkonsistenter Interpretation von 1)...
Viele Grüsse
Philipp
yo Philipp,
Dann wird 1 nicht mehr als internes Attributalias, sondern als Zahl
eines algebraischen Ausdrucks gewertet. Soweit zumindest meine
Vermutung und Schlüsse aus meiner Beobachtung.
wenn ich das mit den ganzzahlen richtig verstanden habe, sollten die immer einen bezug auf die spalten nach dem SELECT haben, ganz ähnlich der syntax mit ORDER BY, sprich die 1 für die erste spalte, 2 für die zweite etc. insofern sollte es eigentlich immer als ein "zahlen-alias" stehen. insofern werde ich noch nicht ganz schlau draus, was dort ein 1+1 bewirkt. meiner meinung würde das die spalte 2 als alias ansprechen sollen...
Obwohl, dass was MySQL in diesem Zusammenhang macht, grenzt schon
fast an schwarze Magie
nun, ich bin wirklich kein abergläubiger mensch. aber mich wundert das noch in einem anderen zusammenhang.
<zitat mysql doku>
Wenn Sie in einem Statement eine Gruppierungsfunktion benutzen, die keine GROUP BY-Klausel enthält, ist das gleichbedeutend mit der Gruppierung aller Zeilen.
<zitat ende>
das an sich ist keine überraschung, vielmehr bin ich davon ausgegangen. wird kein group by angebeben und die aggregat-funktion count(*) benutzt, dann handelt es sich a) um eine gruppierung über die gesamte tabelle und b) wird der wert 0 zurückgegeben, wenn die tabelle leer ist.
benutzt man aber nun explizit ein group by, dann wird bei einer leeren ergebnistabelle keine wert bei count(*) zurück gegeben. das hat mich doch bei dem obigen zitat verwundert.
Ilja
Halihallo Ilja
Dann wird 1 nicht mehr als internes Attributalias, sondern als Zahl
eines algebraischen Ausdrucks gewertet. Soweit zumindest meine
Vermutung und Schlüsse aus meiner Beobachtung.wenn ich das mit den ganzzahlen richtig verstanden habe, sollten die immer einen bezug auf die spalten nach dem SELECT haben, ganz ähnlich der syntax mit ORDER BY, sprich die 1 für die erste spalte, 2 für die zweite etc. insofern sollte es eigentlich immer als ein "zahlen-alias" stehen.
Theoretisch ja. Praktisch haben meine Erfahrungen andere Schlüsse
ergeben. Ich halte es allgemein für inkorrekt, wenn Zahlen als
Attribut-Alias genommen werden (falls diese nicht explizit durch den
Benutzer definiert werden), da diese eben eine duale Bedeutung haben:
Zum einen sind es Zahlen, zum anderen Variablen/Attributwerte und
somit lässt sich schwer eine Syntax definieren, so dass die Semantik
klar ist.
insofern werde ich noch nicht ganz schlau draus, was dort ein 1+1 bewirkt. meiner meinung würde das die spalte 2 als alias ansprechen sollen...
Entweder so, oder es wird der Attributwert des ersten Attributs mit
sich selber addiert... Es ist wie gesagt semantisch nicht eindeutig.
Soweit ich es aufgrund meiner Beobachtungen deute, wird 1+1 als
algebraischer Ausdruck mit *Zahlen* gedeutet. 1 steht hier also für
eine nummerische Zahl und nicht ein Attributwert... Glaub mir, ich
werde auch nicht schlau daraus :-)
Obwohl, dass was MySQL in diesem Zusammenhang macht, grenzt schon
fast an schwarze Magienun, ich bin wirklich kein abergläubiger mensch. aber mich wundert das noch in einem anderen zusammenhang.
<zitat mysql doku>
Wenn Sie in einem Statement eine Gruppierungsfunktion benutzen, die keine GROUP BY-Klausel enthält, ist das gleichbedeutend mit der Gruppierung aller Zeilen.
<zitat ende>das an sich ist keine überraschung, vielmehr bin ich davon ausgegangen. wird kein group by angebeben und die aggregat-funktion count(*) benutzt, dann handelt es sich a) um eine gruppierung über die gesamte tabelle und b) wird der wert 0 zurückgegeben, wenn die tabelle leer ist.
Jep.
benutzt man aber nun explizit ein group by, dann wird bei einer leeren ergebnistabelle keine wert bei count(*) zurück gegeben. das hat mich doch bei dem obigen zitat verwundert.
Hm. Das ist richtig. Die Funktionsweise ist hier anscheinend nicht
genau so umgesetzt, wie in der Doku beschrieben. IMHO ist die
korrekte Umsetzung jene in der Doku und die "SELECT COUNT(*) FROM t
GROUP BY constant-value"-Umsetzung (die, die ich auch schon
vorgeschlagen habe und eben für eine Gruppierung der ganzen Relation
führt) von MySQL bei leerer Relation t "fehlerhaft".
Viele Grüsse
Philipp
yo Philipp,
... Glaub mir, ich
werde auch nicht schlau daraus :-)
vielleicht hat ja 1+1 eine ganz andere bedeutung, sozusagen als alias für uns beide, zwei die nicht schlau daraus werden. die frage ist nun, was zwei nicht schlaue ergibt. werden sie zusammen addiert schlauer oder noch "unschlauer" ? fragen über fragen und wer kennt schon die wahrheit....
Ilja
Halihallo Ilja
vielleicht hat ja 1+1 eine ganz andere bedeutung, sozusagen als alias für uns beide, zwei die nicht schlau daraus werden.
Sehr wahrscheinlich :-)
Wegen MySQL werd ich noch religiös. Ja, ich Glaube an meine Query.
Deine relationale Algebra komme. Deine Optimierung geschehe. Tja,
und am Ende passiert eben doch nix... Oder doch?... Syntax error near
'GROUP BY expr'; toll, naja, aber glauben darf man ja, wa?
die frage ist nun, was zwei nicht schlaue ergibt. werden sie zusammen addiert schlauer oder noch "unschlauer" ? fragen über fragen und wer kennt schon die wahrheit....
In der Doku hab ich nix gefunden, mit meinem Latein am Ende sein tue
ich schon seit der Erkenntniss, dass man MySQL mit 1+1 überlisten
kann und mit Logik hat das nix mehr zu tun...
Einzig bleibt mir der Verdacht (der bestätigte Verdacht, ich will
schon sagen es kommt einer verhärteten These gleich), dass MySQL
eine alleinstehende Zahl in GROUP BY als Attributindex (der zu allem
noch bei 1 zu zählen beginnt! - Schrecklichst!) interpretiert. Wenn
es nicht mehr alleinstehend ist (somit in einer Expression steht), so
transformiert sich diese ominöse Zahl x in einen nummerisch
(aus-)gewerteten Term.
Viele Grüsse
Philipp
yo,
wie auch immer, danke Philipp für deine anregungen, habe was gelernt. auch was das religiöse betrifft.
du sollst keine anderen dbms haben neben mir,
meine query geschehe,
wie auf den Bildschirm,
so auch auf den commputer...
Ilja
Halihallo Ilja
wie auch immer, danke Philipp für deine anregungen, habe was gelernt. auch was das religiöse betrifft.
Gleiches gilt für mich.
du sollst keine anderen dbms haben neben mir,
meine query geschehe,
wie auf den Bildschirm,
so auch auf den commputer...
Ich glaube die erste Zeile lautet anders :-)
Aber frag mich jetzt bloss nicht wie...
Viele Grüsse und gute Nacht
Philipp