Toon posts:

SQL Query - Alleen volledige gegevens vergelijken

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Beste,

Momenteel ben ik bezig met een project om prijzen van verschillende winkels met elkaar te vergelijken. Zo wil ik graag inzicht krijgen op de goedkoopste winkel en inzicht krijgen welke winkel het meeste is gestegen t.o.v. van het voorgaande jaar.

Uitwerking (3 tabellen):

Winkels (ID, Naam, Type, etc.)
Producten (ID, Naam, type, etc.)
Prijzen(WinkelID, ProductenID, Jaar, prijs)

Voorbeeld: Ik wil een vergelijkingen maken op basis van producttypen. Ik wil zien welke winkel het goedkoopste fruit aanbiedt. Normaliter is dit makkelijk omdat je gewoon een filter toepast op enkel de producten met producttype Fruit.

Echter loop ik tegen het volgende probleem:

Stel ik heb van Winkel A alle prijzen van al het fruit in mijn database staan. Winkel B is niet compleet en daar ontbreekt de prijs van de appels. Het toepassen van een som zal een vertekend beeld geven omdat appels ontbreekt bij Winkel B. Winkel B zal hierdoor "goedkoper" zijn.

Is er een mogelijkheid om alleen records mee te nemen waar beide winkels prijzen van heeft?

[ Voor 0% gewijzigd door Verwijderd op 27-06-2017 12:10 . Reden: spelling ]

Alle reacties


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Als je toch al twee winkels tegen elkaar aan moet joinen, dan is een simpele extra check om te zien of het product-ID bij beide winkels not null is toch genoeg?

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Kawaii
  • Registratie: Oktober 2002
  • Niet online
Het lijkt me dat een simpele IS NOT NULL (where) clause voldoende moet zijn?

[ Voor 5% gewijzigd door Kawaii op 27-06-2017 12:11 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Nou wat ik wil bereiken: Als de prijs van appels bij Bedrijf A ontbreekt wil ik dat de prijs van Appels bij bedrijf B niet wordt meegenomen in totale vergelijking van fruit tussen bedrijf a en b". Volgens mij is dit niet met een IS NOT NULL op te lossen?

[ Voor 6% gewijzigd door Verwijderd op 27-06-2017 13:15 ]


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Dat hangt ervan af hoe je query nu in elkaar zit. Je bent sowieso aan het joinen en aan het summen, waarom zou daar geen check op ID's bij kunnen? Of inner joins gebruiken in plaats van outer joins.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Robicide
  • Registratie: Maart 2016
  • Laatst online: 14:04
Kijk eens naar MIN() en GROUP BY. Check voor elk product wat de laagste prijs is en kijk daarna welke winkel die prijs heeft.

Je kan ook eerst alle producten ophalen waar twee of meer prijzen van bekend zijn. Hiervoor kun je HAVING gebruiken, da's een tegenhanger van WHERE die specifiek is voor aggregaties (MIN, MAX, COUNT, etc)

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Dat eerste is niet wat hij vraagt. ;) HAVING COUNT(ProductId) = 2 zou wel kunnen maar dat hangt een beetje van de query af omdat je daar data mee weg groepeert die hij volgens mij wel wil tonen. Ik vermoed dat het in de join regelen makkelijker is.

[ Voor 92% gewijzigd door NMe op 27-06-2017 17:10 ]

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • KraveN
  • Registratie: November 2001
  • Laatst online: 08-10 23:43
Misschien omslachtig op dit tijdstip :)

Als je op je prijzen tabel, het winkelid even loslaat en een min(prijs) opvraagt per product en jaar. Dan krijg je als het goed is een lijst met de minimale prijs per product, per jaar. Als je hier vervolgens dan de 0 of null velden uitfilterd kun je deze uitvraag vervolgens gebruiken om alles op te joinen althans je hebt dan alleen nog maar producten/jaren waarvan een prijs bekend is.

Wellicht moet je er nog even voor zorgen dat je op het moment dat er geen waarde bekend is dit wegschrijft naar 0 ipv null. Weet even niet uit mijn hoofd of min(prijs) een 0 voorrang geeft op null.

Daarnaast doe ik de aanname dat fruit niet gratis wordt aangeboden lees 0.

[ Voor 5% gewijzigd door KraveN op 28-06-2017 03:31 ]


Acties:
  • 0 Henk 'm!

  • Robicide
  • Registratie: Maart 2016
  • Laatst online: 14:04
NMe schreef op dinsdag 27 juni 2017 @ 17:09:
[...] omdat je daar data mee weg groepeert die hij volgens mij wel wil tonen. [...]
Dat is niet wat ik hieruit lees:
Is er een mogelijkheid om alleen records mee te nemen waar beide winkels prijzen van heeft?
Het antwoord hierop is dan ook "Ja, HAVING COUNT(*) = 2" :)

Om dat wat futureproof te maken (mocht je in de toekomst meer winkels gaan toevoegen) zou je daar uiteraard HAVING COUNT(*) > 1 van kunnen maken.

Acties:
  • +2 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Robicide schreef op woensdag 28 juni 2017 @ 09:19:
[...]


Dat is niet wat ik hieruit lees:


[...]


Het antwoord hierop is dan ook "Ja, HAVING COUNT(*) = 2" :)
Nogmaals, dat hangt van de query die de TS niet lijkt te willen delen af. HAVING werkt alleen met grouping en als je de data die je hierbij zou moeten groeperen nodig hebt kan wat je hier roept niet.
Om dat wat futureproof te maken (mocht je in de toekomst meer winkels gaan toevoegen) zou je daar uiteraard HAVING COUNT(*) > 1 van kunnen maken.
Dat is helemaal niet future proof want als je dan wil vergelijken met 3 winkels krijg je ook producten terug die slechts bij 2 winkels te koop zijn.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ooh nou ik deel graag mijn query, maar aan mijn "gebakken lucht" van gisteren hebben jullie niets haha. Momenteel heb ik de volgende query en met verschillende testronden blijkt de query te werken:

Ik heb allereerst query's aangemaakt die gegevens weergeven van één specifieke winkel. Daarna heb ik beide query's samengevoegd en tegen elkaar opgezet:

Select Sum(plus.prijs2017) AS Plus, Sum(albertheijn.prijs2017) AS AlbertHeijn
FROM PLUS Inner join albertheijn ON plus.productID = albertheijn.productID
Where plus.producten.type = [Forms]![Vergelijken]![Productgroep]

Nu werkt de query na behoren en worden daadwerkelijk alleen gegevens geselecteerd waar bij beide winkels de prijs beschikbaar is. Nu zie ik wel de bui hangen als ik 10 winkels ga toevoegen...Dan wordt het een groot karwei om deze query's allemaal te koppelen. Hebben jullie tips?

Hartelijk dank voor jullie meedenken!

Acties:
  • +1 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Je zal dan ofwel joins en wheres erbij moeten schrijven op dezelfde manier totdat het werkt, ofwel toch met group by en having aan de slag gaan, maar dan heb je bovengenoemde beperkingen.

Overigens weet ik niet of je controle over je datamodel hebt, maar een tabel per supermarkttype en een kolom per prijs per jaar is niet bepaald goed database-design. Mocht je daar de vrijheid toe hebben zou ik iets bijlezen over databasenormalisatie en die info toepassen. ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Top, daar heb ik toegang tot. Tijdens mijn ontwerp had ik al twijfels over de prijs per jaar. Ben momenteel bezig om een jaar kolom te maken en een prijs kolom. Hartelijk dank!

Acties:
  • +1 Henk 'm!

  • Rotterdammertje
  • Registratie: Juni 2002
  • Laatst online: 28-03-2023
Je kan alle producten opvragen die in alle winkels verkocht worden:

SQL:
1
2
3
4
5
6
7
select prod.id, prod.naam
from producten prod
where not exists (
 select w.id from Winkels w
 left outer join Prijzen pr on (pr.winkel_id = w.id and pr.jaar = 2017 and pr.product_id = prod.id)
 where pr.winkel_id is null
);


Met andere woorden: geef alleen die producten waarvoor alle winkels een prijs hebben opgegeven in het specifieke jaar.

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


Acties:
  • +1 Henk 'm!

  • Dido
  • Registratie: Maart 2002
  • Laatst online: 13:52

Dido

heforshe

@Rotterdammertje Dat is wel heel omslachtig, want met een gewone inner join ben je er ook. Hoef je geen left join te doen in een subquery.

@Verwijderd
Sowieso zie ik het probleem niet zo, want een normale inner join (dus ook een "gewone" join) geeft sowieso alleen resultaten als beide delen van de join niet null zijn.

Wat betreft queries die moeilijk worden als je, zoals je laat zien in je werkende query, een tabel per supermarkt hebt. Dat is nooit een goed idee.

[ Voor 18% gewijzigd door Dido op 28-06-2017 10:18 ]

Wat betekent mijn avatar?


Acties:
  • 0 Henk 'm!

  • Rotterdammertje
  • Registratie: Juni 2002
  • Laatst online: 28-03-2023
@Dido : Hoe ziet een query met een gewone inner join er dan uit?

[ Voor 50% gewijzigd door Rotterdammertje op 28-06-2017 10:22 ]

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


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dido schreef op woensdag 28 juni 2017 @ 10:17:
@Verwijderd
Wat betreft queries die moeilijk worden als je, zoals je laat zien in je werkende query, een tabel per supermarkt hebt. Dat is nooit een goed idee.
Dat is niet het geval. Alle prijzen komen samen in een tabel. Waar de sleutel WinkelID, ProductID en Jaar is. (Jaar moet ik nog verwerken, aangezien ik eerst een kolom per jaar maakte)

In de "hoofd"query lijkt dit omdat ik per winkel een aparte query heb aangemaakt die filtert op de prijzen van de bijbehorende winkel, maar zoals ik het hier lees is dat helemaal niet noodzakelijk.
Pagina: 1