[MySQL] Self join met mogelijk ontbrekende data

Pagina: 1
Acties:

  • Mythica
  • Registratie: Juli 2006
  • Laatst online: 01-03-2024
Hallo mensen,
Ik kom wel vaker op GoT om wat op te zoeken, maar nu is voor het eerst een moment aangebroken dat ik ergens zelf de oplossing niet van heb én niet van kan vinden. Dus hoogste tijd voor m'n eerste post :)

Ik heb in MySQL (v5.0.22) een tabel met een structuur die hierop lijkt:

spelers
spelerdatumwedstrijdenpunten
M1154029668219
Q115402966818
M1154040090411
Q1154040090514


Periodiek wordt van alle spelers het aantal gespeelde wedstrijden en het aantal verkregen punten in de tabel opgeslagen. De datum van dit "snapshot" wordt opgeslagen in het veld datum.

Als ik twee data kies, wil ik ik een overzicht waarin de gegevens (# wedstrijden & # punten) van de twee data naast elkaar staan. Je krijgt dan zoiets:

spelerwedstijdenpuntenwedstrijdenOudpuntenOud
M411219
Q51419


Dit kan prima met een self outer join. Ik gebruik hiervoor deze query:

SQL:
1
2
3
4
5
6
7
8
9
10
SELECT s1.speler,
s1.wedstrijden,
s1.punten,
s2.wedstrijden AS wedstrijdenOud,
s2.punten AS puntenOud
FROM spelers s1
LEFT OUTER JOIN spelers s2
ON (s1.speler = s2.speler)
WHERE s1.datum = 1154040090
AND s2.datum =  1154029668


Nou werkt dit prima, totdat er een speler is bijgekomen. Met andere woorden, de speler is wel aanwezig toen het nieuwere snapshot werd genomen, maar niet toen het oudere snapshot werd genomen. Dat ligt ongetwijfeld aan de JOIN clause (s1.speler = s2.speler) want s2.speler (refererend aan het oude snapshot) bestaat in dat geval niet.
Ook het omgekeerde is mogelijk, dat een speler is gestopt (wel op ouder snapshot, niet meer op nieuwer). In deze gevallen, wil ik dat de relevante waarden gewoon NULL zijn, maar dat krijg ik niet voor elkaar.

Ik hoop dat ik het een beetje duidelijk heb uitgelegd :). Ik heb de GoT search gebruikt, maar kon niks relevants vinden. Iemand een idee hoe dit kan gedaan kan worden?? :)

  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
Zoiets misschien?
SQL:
1
2
3
4
5
6
7
8
9
10
SELECT s1.speler,
s1.wedstrijden,
s1.punten,
s2.wedstrijden AS wedstrijdenOud,
s2.punten AS puntenOud
FROM spelers s1
FULL OUTER JOIN spelers s2
ON (s1.speler = s2.speler)
WHERE (s1.datum = 1154040090 OR s1.speler IS NULL)
AND (s2.datum =  1154029668 OR s2.speler IS NULL)

Dus een FULL OUTER JOIN gebruiken en (OR speler IS NULL) toevoegen.

Never underestimate the power of


  • Mythica
  • Registratie: Juli 2006
  • Laatst online: 01-03-2024
MySQL ondersteunt helaas geen FULL OUTER JOINs, maar je oplossing ziet er wel goed uit. Is het mogelijk de query te herschrijven met wat mooie constructies of is het verstandiger naar Postgresql te migreren? Host heeft 't dus is geen probleem :)

  • _js_
  • Registratie: Oktober 2002
  • Laatst online: 13-01 07:19
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
SELECT s1.speler,
s1.wedstrijden,
s1.punten,
s2.wedstrijden AS wedstrijdenOud,
s2.punten AS puntenOud
FROM spelers s1
LEFT OUTER JOIN spelers s2
ON (s1.speler = s2.speler)
WHERE (s1.datum = 1154040090)
AND (s2.datum =  1154029668 OR s2.speler IS NULL)
UNION ALL
SELECT s1.speler,
s1.wedstrijden,
s1.punten,
s2.wedstrijden AS wedstrijdenOud,
s2.punten AS puntenOud
FROM spelers s1
RIGHT OUTER JOIN spelers s2
ON (s1.speler = s2.speler)
WHERE (s1.speler IS NULL)
AND (s2.datum =  1154029668)
Volgens mij zou dit op MySQL moeten werken.

  • Mythica
  • Registratie: Juli 2006
  • Laatst online: 01-03-2024
De query werkt uitstekend, alleen de spelers die maar in een van de twee snapshots voorkomen, staan er nogsteeds niet tussen....

  • moozzuzz
  • Registratie: Januari 2005
  • Niet online
Is dit niet mogelijk? Combi van vorige oplossingen?
SQL:
1
2
3
4
5
6
7
8
9
10
SELECT s1.speler,
s1.wedstrijden,
s1.punten,
s2.wedstrijden AS wedstrijdenOud,
s2.punten AS puntenOud
FROM spelers s1
LEFT OUTER JOIN spelers s2
ON (s1.speler = s2.speler)
WHERE (s1.datum = 1154040090 OR s1.speler IS NULL)
AND s2.datum =  1154029668 OR s2.speler IS NULL)
Niet getest overigens...

  • Mythica
  • Registratie: Juli 2006
  • Laatst online: 01-03-2024
Nee, dat werkt ook niet. De oplossing speler IS NULL werkt denk ik niet. Het probleem is dat de entry gewoon helemaal ontbreekt.

  • moozzuzz
  • Registratie: Januari 2005
  • Niet online
Is het veld wedstrijden standaard op Null gezet of komt er bvb 0 in te staan?

  • Mythica
  • Registratie: Juli 2006
  • Laatst online: 01-03-2024
Alle velden zijn altijd ingevuld, dus als iemand nog nooit heeft gespeeld staat het aantal wedstrijden idd op 0.
Pagina: 1