Zitat von protestix
Beitrag anzeigen
Ankündigung
Einklappen
Keine Ankündigung bisher.
PostgreSQL: Join klappt nicht.
Einklappen
Neue Werbung 2019
Einklappen
X
-
-
Alf2016
Was ist an meiner Lösung unsauber?
@beweise
Dass man in einem Forum beweisen muss, dass eine richtige oder bessere Lösung vorliegt, wäre mir neu. Sinnvoll wäre immerhin, dass sie nachvollziehbar ist. Das ist aber Ermessenssachem, erst Recht wenn es um "besser" geht. Vor allem wäre spannend, ob es für den TE interessant ist, wenn er bspw. zufällig sowieso gerade sein Datenmodell neu macht.
Also ist es im Zweifel Spielerei oder eine Frage von Rechthaberei oder wer hat den längeren.
Kommentar
-
Wenn ich schreibe, dass das Ergebnis stimmt, dann ist das auch so. Evtl. verwirrt das rowid, ich gebe immer dem ersten Feld jeder Tabelle die Bezeichnung rowid. Der Hinweis auf die 2 INNER JOINS und WHERE ist richtig, allerdings arbeite ich schon lange genug mit SQLite, dass ich genau weiß wann ein subselect einem inner join vorzuziehen ist. Hierüber will ich aber auch nicht diskutieren, weil es in den Bereich der Mikrooptimierung fällt.
Das äußere select "select playername from" kann man auch weglassen, dass habe ich nur zur Veranschaulichung der except Geschichte geschrieben.
es würde auch folgendes reichen:
Anwesend:
Code:select playername from (select player_id,(select rowid from trainings where datum = '2019-01-01') as trainID from teilnahme where training_id = trainID) inner join player on player.rowid = player_id
Code:select playername from player except select playername from (select player_id,(select rowid from trainings where datum = '2019-01-01') as trainID from teilnahme where training_id = trainID) inner join player on player.rowid = player_id
Kommentar
-
Zitat von Alf2016 Beitrag anzeigenOffenbar haben sich oberste Stellen darauf geeinigt, daß subselects statt joins undCode:SELECT *
Ja, dazu ist ein Forum da, um dazu zu lernen. Das kann man einfach so nutzen, ohne dass Grabenkämpfe zu Rangordnungen oder was auch immer ausgeführt werden müssen.
Ich habe in meinem Beitrag begründet, warum ich den Stern verwendet habe. Subselects habe ich nicht verwendet, sie sind oft ungünstig, bzw. produzieren ungünstiges Ausführungsverhalten, verstoßen aber allgemein nicht gegen irgendwelche mir bekannten Codierungsgepflogenheiten.
Und auch wenn Du es anders siehst, ich habe keine Beweise nötig, ich schreibe nicht Dir, sondern dem TE. Wenn er meinen Vorschlag ausprobiert und gut findet ok, wenn er ihn nicht versteht oder doof findet, auch ok. Die meisten sind ja des Schreibens mächtig und können sich dann entsprechend äußern, wenn sie möchten.
Damit bin ich zu gar nichts verpflichtet, außer die Forenregeln einzuhalten.
Vielleicht kannst Du mir noch schreiben, wie Du dazu kommst, von "die oberen" zu schreiben.
- 2 Likes
Kommentar
-
Zitat von Perry Staltic Beitrag anzeigen...
Vielleicht kannst Du mir noch schreiben, wie Du dazu kommst, von "die oberen" zu schreiben.
Kommentar
-
Zitat von Alf2016 Beitrag anzeigenAber das Stilmittel der Ironie ist dir doch bekannt? ..
Ich sehe in Deinem Beitrag leider keine Antworten zu meinen Punkten. Und ich weiß auch sonst nicht, was Deine Worte aus #37 mir und anderen sagen sollen. Teilweise kann ich immerhin zustimmen, die genannten Mitglieder liefern gute Beiträge. Und erlaube mir, es Dir gleich zu tun: Manche von den Beiträgen, die ich von Dir gelesen hab sind auch ok. Ansonsten verbreitest Du leider auch viel Stunk und sagen wir mal heiße Luft. Das kannte ich so im Forum bis jetzt nicht.
Vielleicht kannst Du ja etwas damit anfangen, dass sich solche Foren auch Community nennen. Hier geht es tatsächlich um gemeinschaftliches Lernen, nichts anderes.
- 2 Likes
Kommentar
-
Zitat von kaminbausatz Beitrag anzeigen@erc
Riesenwind und keine Lösung...
Was zum nachdenken für dich:
Zitat von kaminbausatz Beitrag anzeigenWenn ich schreibe, dass das Ergebnis stimmt, dann ist das auch so.
Zitat von kaminbausatz Beitrag anzeigenallerdings arbeite ich schon lange genug mit SQLite, dass ich genau weiß wann ein subselect einem inner join vorzuziehen ist. Hierüber will ich aber auch nicht diskutieren, weil es in den Bereich der Mikrooptimierung fällt.
B. Wie bereits angedeutet ist dieser Subquery auch falsch platziert. Die (gedankliche) Rangfolge der SQL Klauseln ist FROM -> WHERE -> SELECT -> HAVING -> GROUP BY -> ORDER BY. Dein WHERE bezieht sich auf ein Ergebnis im SELECT, was aber das WHERE erst bildet. Das geht in Sqlite, ist aber unlogisch. Du verwendest diesen Wert dann auch nicht (hier fehlte dann die Lust auf Mikrooptimierung?) und durch die Positionierung im SELECT unterliegt das Ergebnis des Subqueries einschränkungen, siehe oben und weiter unten. Im WHERE könntest du das mit =,in,any,all sinnvoll Formulieren.
Zitat von kaminbausatz Beitrag anzeigenWenn einer diese simplen Zeilen nicht nachvollziehen kann, so ist das nicht mein Problem.
Zitat von kaminbausatz Beitrag anzeigenEs ging auch hauptsächlich darum, auf den Cross Join zu verzichten[...]
Zitat von kaminbausatz Beitrag anzeigenSarkastisches Augenrollen sollte man sich sparen, wenn man nicht 100% im Thema ist. Der Sinn eines subselects ist die Rückgabe eines einzelnen Wertes. Joins werden benutzt um rows zurückzugeben.
- 1 Likes
Kommentar
-
Zitat von Perry Staltic Beitrag anzeigenJa natürlich, ich kann nicht nur SQL ich kann auch Ironie.
Ich sehe in Deinem Beitrag leider keine Antworten zu meinen Punkten. Und ich weiß auch sonst nicht, was Deine Worte aus #37 mir und anderen sagen sollen. Teilweise kann ich immerhin zustimmen, die genannten Mitglieder liefern gute Beiträge. Und erlaube mir, es Dir gleich zu tun: Manche von den Beiträgen, die ich von Dir gelesen hab sind auch ok. Ansonsten verbreitest Du leider auch viel Stunk und sagen wir mal heiße Luft. Das kannte ich so im Forum bis jetzt nicht.
Vielleicht kannst Du ja etwas damit anfangen, dass sich solche Foren auch Community nennen. Hier geht es tatsächlich um gemeinschaftliches Lernen, nichts anderes.
erc Du hast eine pn.
Kommentar
-
Zuletzt geändert von kaminbausatz; 14.03.2019, 09:47.erc
Ich verzichte mit Bedacht darauf, deine Ausführungen zu zitieren, das ermöglicht dir die reichlich vorhandenen Rechtschreibfehler zu korrigieren. Ich hoffe ja, dass du nicht ebenso programmierst.
Diese Spitze musste einfach sein, sorry.
Im Einzelnen:
„füge ein weiteres Training für ein vorhandenes Datum ein“, müsste da nicht auch die Tabelle trainings ein weiteres Unterscheidungsmerkmal aufweisen?
Die Struktur wurde vorgegeben.
Über die Subquery will ich nicht diskutieren, solange du mir kein schnelleres Beispiel zeigst. Eine Suche nach 'join vs. subquery' liefert sehr viele unterschiedliche Ergebnisse. Das scheint ein Fall für die Kirche zu sein.
Das Problem habe ich nicht geändert, der TE wollte wissen, wer an an welchem Tag nicht beim Training war. Das erklärt auch deine letzte Anmerkung. Ich wollte beabsichtigt nur den einen Datensatz.
Ich weiß nicht, von welchem SQL Fehler du redest, habe leider die Daten nicht mehr auf dem Handy. Werde sie allerdings auch nicht mehr neu eingeben, weil es sicher und zuverlässig funktioniert. Ich habe das getestet.
Die Diskussion entstand ja nur, weil ich in #11 bereits andeutete, dass ich bei Cross-Joins immer vorsichtig bin, wenn ich das Datenvolumen nicht kenne.
Ich bediene mich jetzt mal aus deinem Wortschatz. Es ist „Bullshit“ einen riesigen Cross-Join zu erzeugen, wenn ich auf dem Bildschirm nur max. 30 Zeilen mit 8 Spalten oder auf dem einzelnen DIN A4 Ausdruck nur max. 80 Zeilen mit 7 Spalten betrachten kann.
Wenn ein Cross-Join eingesetzt wird, dann nur mit vorhersehbarem definiertem Umfang, sonst kann man dies als "groben Unfug" bezeichnen.
Ist eine Liste gewünscht, würde ich das Problem in SQLite eher wie folgt anpacken. Ich schreibe SQLite, weil ich es diesmal nicht getestet habe, aber sicher bin, dass es so in SQLite funktioniert.
Code:SELECT datum, player.playername, count(*)%2 as anwesend FROM trainings JOIN teilnahme ON teilnahme.training_id != trainings.trainings_id JOIN player ON player.player_id = teilnahme.player_id where datum >= '2019-01-01' and datum < '2019-10-10' Group by datum, playername
Kommentar
-
Zitat von kaminbausatz Beitrag anzeigenerc
Ist eine Liste gewünscht, würde ich das Problem in SQLite eher wie folgt anpacken. Ich schreibe SQLite, weil ich es diesmal nicht getestet habe, aber sicher bin, dass es so in SQLite funktioniert.
Code:SELECT datum, player.playername, count(*)%2 as anwesend FROM trainings JOIN teilnahme ON teilnahme.training_id != trainings.trainings_id JOIN player ON player.player_id = teilnahme.player_id where datum >= '2019-01-01' and datum < '2019-10-10' Group by datum, playername
Kommentar
-
Jetzt sind wir schon bei den Rechtschreibfehlern!
Zum Sachverhalt bei Cross Joins:
Vorsicht ist sicher nicht verkehrt, wobei es wie so oft mit den Fehlern ist, man macht es nicht absichtlich.
Ein Cross Join kann ohne weiteres mit einer Where Clause beschnitten werden und verhält sich entsprechend brav.
Code:select *, case when training_id is null then 'nicht anwesend' else 'anwesend' end as generated_remark from player p cross join trainings t left join player_training pt on (t.tid, p.pid) = (pt.training_id,pt.player_id) where tdate between '2019-02-02'::date and '2019-04-02'::date -- oder ... -- tdate < CURRENT_DATE - INTERVAL '45 day')::date -- älter als 45 Tage -- tid = 3 -- genau 1 bestimmtes Training nach ID -- tid in (3,5,6) -- genau 3 bestimmte Trainings nach ID -- tdate = '2019-02-02'::date -- Trainings eines Tages order by <ReplaceWithWhatEverYouNeed>
Und die Diskussion Subselect oder Join kann so gar nicht geführt werden. Man müsste das nicht nur DB spezifisch machen, sondern auch das Datenmodell, die Mengengerüste, die Werteverteilung und die Indizierung berücksichtigen.
M.E. macht es nicht viel Sinn, sich darüber zu streiten, ob man einen deterministischen Weg durch die Gehirnwindungen des Optimizer Developer Teams findet. Selbst mit festem Datenmodell machen die Daten selbst einem einen Strich durch die Rechnung.
- 1 Likes
Kommentar
-
Zitat von Perry Staltic Beitrag anzeigen...Ein Cross Join kann ohne weiteres mit einer Where Clause beschnitten werden und verhält sich entsprechend brav.
Code:select *, ... where tdate between '2019-02-02'::date and '2019-04-02'::date ... order by <ReplaceWithWhatEverYouNeed>
Code:SELECT A.trainingsdatum, IF(ISNULL(training_id), "fehlt", "teilgen.") AS Teilnahme, A.name FROM player_training RIGHT JOIN (SELECT player.id AS pid, player.name, trainings.id AS tid, trainings.trainingsdatum FROM player, trainings) as A ON player_training.player_id = A.pid AND player_training.training_id = A.tid ORDER BY A.trainingsdatum, Teilnahme DESC, A.name;
Oder eben wie AKretschmer PostgreSQL verwenden, es aber richtig bedienen können (bzw. die Fehler, die es macht, erkennen können, denn das Ergebnis war ja nun wirklich ganz offensichtlich fehlerhaft...). Aber auch da kann ich mir vorstellen, daß eine saubere Feldliste statt "*" und eine sinnvolle Sortierung hilfreich sein könnte...
Zur Performance-Debatte, die Perry Staltic ja dankenswerterweise eigentlich schon vom Tisch gefegt hatte:...
M.E. macht es nicht viel Sinn, sich darüber zu streiten, ob man einen deterministischen Weg durch die Gehirnwindungen des Optimizer Developer Teams findet. Selbst mit festem Datenmodell machen die Daten selbst einem einen Strich durch die Rechnung.
Aber das hat man über die Theorie-Debatte und im Eifer des Gefechts - oh, sorry: über "das gemeinschaftliche Lernen" - glatt vergessen...
Ich denke, diesen Thread kann man nun wirklich auch schließen. Aber bitte, wenn jemand noch ein Wort zum Samstag anschließen möchte, ich will mich da nicht vordrängen... Für mich ist alles gesagt.
Kommentar
-
Zitat von Alf2016 Beitrag anzeigenOder eben wie AKretschmer PostgreSQL verwenden,
Überschrift des Threads:
PostgreSQL: Join klappt nicht.
LG jspit
- 5 Likes
Kommentar
Kommentar