SQL-query die rijen in één tabel met elkaar vergelijkt

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Jovatov
  • Registratie: April 2008
  • Laatst online: 18:14
Mijn vraag

Ik ben nu dik een half jaar bezig in de IT als software tester en schrijf vooral simpele queries, maar nu heb ik een wat ingewikkelder iets waar ik uit probeer te komen. Het gaat om het volgende:

Ik heb een enorme tabel met daarin verschillende waarden, die ongeveer als volgt is opgebouwd.
IDKlantTypeFormaat
1AHoofdklein
2ASubAklein
3ASubBklein
4BHoofdmiddel
5BHoofdmiddel
6BSubAklein
7CHoofdgroot
8CHoofdgroot
9CSubBgroot



Nu is er in deze tabel een fout geslopen waarbij het formaat niet altijd goed aangepast wordt via de software. De regel is dat het formaat van het type hoofd van een klant bepalend is voor het formaat van het type suba/subb.

Dus als type hoofd formaat klein heeft, dan zouden type suba/subb voor die klant ook formaat klein moeten hebben.

In het voorbeeld hier boven gaat het dus fout in de regel met ID 6, het type hoofd heeft formaat middel, en dus zou het type suba, ook behorend bij klantnummer B, ook formaat middel moeten hebben, maar dat is kennelijk fout gegaan en toch klein.

De vraag is hoe ik in SQL alle rijen kan selecteren waarbij het formaat afwijkend is bij type suba/subb aan het type dat voor datzelfde klantnummer groen is.

Relevante software en hardware die ik gebruik
Micorsoft SQL Server Management Studio

Wat ik al gevonden of geprobeerd heb
Ik heb wat zitten klooien met self joins en subqueries, maar ik kom er niet uit. Telkens als ik een query schrijf en het voor mezelf simpel probeer te houden lukt het niet omdat ik te weinig info/regels selecteer om een vergelijking te maken.

Maar als ik het ingewikkelder maak met een self join/ subqueries of Group By/Having raak ik ook gauw het spoor bijster.

Heeft iemand een duwtje in de goede richting?

Beste antwoord (via Jovatov op 19-08-2019 15:21)


  • vdws
  • Registratie: December 2010
  • Laatst online: 10-09 20:58
Zoiets?
code:
1
2
3
4
5
6
7
8
select tab1.id
from klanttabel tab1
where tab1.type != 'Hoofd'
and not exists (
     select 1 from klanttabel tab2 
     where tab2.klant = tab1.klant 
     and tab2.type = 'Hoofd' 
     and tab2.formaat = tab1.formaat);

Alle reacties


Acties:
  • +1 Henk 'm!

  • DJMaze
  • Registratie: Juni 2002
  • Niet online
Jammer dat je zelf geen voorbeelden gaf van je frutsels, we verwachten hier eigen inzet.
Het is ook niet ingewikkeld hoor, gewoon wat alledaagse logica.
SQL:
1
2
FROM tabel a
INNER JOIN tabel b ON (b.Klant = a.Klant AND NOT b.Type = a.Type AND NOT b.Formaat = a.Formaat)


Verder klopt gewoon de DB structuur niet a.d.h.v. de logica.
Iemand heeft geprutst in de software. Niet erg als je junior bent, wel erg voor een bedrijf.

[ Voor 32% gewijzigd door DJMaze op 13-08-2019 14:01 ]

Maak je niet druk, dat doet de compressor maar


Acties:
  • +3 Henk 'm!

  • ShitHappens
  • Registratie: Juli 2008
  • Laatst online: 09-09 12:54
De regel is dat het formaat van het type hoofd van een klant bepalend is voor het formaat van het type suba/subb.
Dan is de database eigenlijk gewoon verkeerd ontworpen, en mist een stapje normalisatie.

Dan zou je zeggen dat deze tabel uitgesplitst moet worden in 2 tabellen:
- Eentje met Klant en Formaat
- Eentje met Klant en Type

Maar met een INNER JOIN zouden deze rijen te selecteren moeten zijn, en dus ook te updaten.

Acties:
  • 0 Henk 'm!

  • BernardV
  • Registratie: December 2003
  • Laatst online: 10-09 14:37
Dit lijkt me niet het enige probleem. De data van id 4,5 en 7,8 zijn identiek. Dat lijkt me ook niet de bedoeling.

Acties:
  • 0 Henk 'm!

  • ShitHappens
  • Registratie: Juli 2008
  • Laatst online: 09-09 12:54
Afhankelijk van de context kan het gewoon de bedoeling zijn. Stel je voor dat 't bestellingen zijn (met bijvoorbeeld een datumveld wegversimpeld) is er niets op tegen ;)

Acties:
  • 0 Henk 'm!

  • Jovatov
  • Registratie: April 2008
  • Laatst online: 18:14
Dank voor de reacties.

Dat de logica van de tabel niet klopt ligt vooral aan mijn eigen versimpeling van de tabel. Daarmee heb ik mijn vraag ben ik bang ook te simpel gesteld zie ik nu.

Feit is namelijk dat er voor dezelfde klant meerdere types kunnen zijn. Dit komt meer in de buurt van de werkelijke tabel.

IDKlantTypeFormaatVolgnummer
1AHoofdklein1
2ASubAklein2
3ASubBklein3
4BHoofdmiddel1
5BHoofdmiddel2
6BSubAklein3
7BHoofdgroot4
8BHoofdgroot5
9BSubBgroot6


Maar daarmee hebben jullie me wel op het goede spoor gebracht. Ik zal iets met een vergelijking tussen een min en max volgnummer kunnen doen, vermoed ik. Ik ga verder puzzelen :)

  • Rotterdammertje
  • Registratie: Juni 2002
  • Laatst online: 28-03-2023
Dus het formaat zou moeten worden bepaald door de records met volgnummer 1? Dan:

- zoek alle records met volgnummer 1
- join alle records met gelijk klantnummer en volgnummer > 1 en ongelijk formaat

main = putStr (q ++ show q); q = "main = putStr (q ++ show q); q = "


Acties:
  • Beste antwoord
  • 0 Henk 'm!

  • vdws
  • Registratie: December 2010
  • Laatst online: 10-09 20:58
Zoiets?
code:
1
2
3
4
5
6
7
8
select tab1.id
from klanttabel tab1
where tab1.type != 'Hoofd'
and not exists (
     select 1 from klanttabel tab2 
     where tab2.klant = tab1.klant 
     and tab2.type = 'Hoofd' 
     and tab2.formaat = tab1.formaat);

Acties:
  • 0 Henk 'm!

  • Jovatov
  • Registratie: April 2008
  • Laatst online: 18:14
vdws schreef op donderdag 15 augustus 2019 @ 13:22:
Zoiets?
code:
1
2
3
4
5
6
7
8
select tab1.id
from klanttabel tab1
where tab1.type != 'Hoofd'
and not exists (
     select 1 from klanttabel tab2 
     where tab2.klant = tab1.klant 
     and tab2.type = 'Hoofd' 
     and tab2.formaat = tab1.formaat);
Ik ben er vandaag weer mee aan de gang geweest, en mijn (werkende) query ziet er inderdaad zo ongeveer uit.
Eerst alles selecteren en dan alleen die records selecteren waarbij er het bijhorende formaat-record niet bestaat en dus afwijkt. d:)b

[ Voor 9% gewijzigd door Jovatov op 19-08-2019 15:23 ]

Pagina: 1