[SQL] Query probleempje

Pagina: 1
Acties:
  • 147 views sinds 30-01-2008
  • Reageer

  • Brynnie
  • Registratie: Februari 2001
  • Niet online
Ik heb een tabel die er als volgt uitziet:

PID - CatKenID - Waarde

6789 - 12 - EDO RAM
4527 - 12 - DDR RAM
6544 - 12 - EDO RAM
6789 - 15 - 64 MB
4527 - 15 - 32 MB
6544 - 15 - 64 MB

Nu moet ik met een query de records eruit halen, waar (CatKenID = 12) AND (Waarde = "EDO RAM") en waar (CatKenID = 15) AND (Waarde = "64 MB")

Dus als CatKenID = 12 moet de Waarde "EDO RAM" zijn, dus de 2e record in het vb mag niet getoond worden. En als CatKenID = 15 dan moet de Waarde "64 MB" zijn, dus de voorlaatste record mag ook niet getoond worden.

Mijn eerste indruk was dat dit niet zo'n moeilijke query zou zijn, maar ik kom er niet uit.

Ik gebruik MS SQL Server 7. Is er iemand die mij het licht aan het eind van de tunnel kan tonen?

  • Basszje
  • Registratie: Augustus 2000
  • Laatst online: 17:07

Basszje

Reisvaap!]

Op maandag 10 september 2001 12:40 schreef Brynnie het volgende:

Nu moet ik met een query de records eruit halen, waar (CatKenID = 12) AND (Waarde = "EDO RAM") en waar (CatKenID = 15) AND (Waarde = "64 MB")

Dus als CatKenID = 12 moet de Waarde "EDO RAM" zijn, dus de 2e record in het vb mag niet getoond worden. En als CatKenID = 15 dan moet de Waarde "64 MB" zijn, dus de voorlaatste record mag ook niet getoond worden.
Iets van

select * from tbl_bla where ( CatkenID = 12 and waarde="edo" ) or ( catken=15 and waarde = "64" ).

Zoiets :? ( losse pols werk, misschien nog wat aanpassingen :) )

Beware of listening to the imposter; you are undone if you once forget that the fruits of the earth belong to us all, and the earth itself to nobody.


  • Brynnie
  • Registratie: Februari 2001
  • Niet online
Dat dacht ik ook, maar dan toont hij de foute records, want hij mag enkel de records tonen waar (CatKenID = 12) AND (Waarde = "EDO RAM") en waar (CatKenID = 15) AND (Waarde = "64 MB").

In jouw geval toont hij alle records waar (CatKenID = 12) AND (Waarde = "EDO RAM") EN alle records waar (CatKenID = 15) AND (Waarde = "64 MB").

De query mag enkel de records tonen waar aan beide voorwaarden voldaan is. In het vermelde voorbeeld zou den wel alle correcte records getoond worden, maar als er bvb een record bij zou zitten als dit:

PID - CatKenID - Waarde

123547 - 12 - EDO RAM
123547 - 15 - 128 MB

Dan zou hij dat ook tonen, en dat mag niet...

  • Basszje
  • Registratie: Augustus 2000
  • Laatst online: 17:07

Basszje

Reisvaap!]

Op maandag 10 september 2001 12:51 schreef Brynnie het volgende:
In jouw geval toont hij alle records waar (CatKenID = 12) AND (Waarde = "EDO RAM") EN alle records waar (CatKenID = 15) AND (Waarde = "64 MB").
Check de haakjes . Die moet je niet per Var doen, maar over de hele verglijking zodat ie ze samentrekt.,

Zoals in bovenstaande voorbeeld dus .
Je zet de haakjes anders neer.

Beware of listening to the imposter; you are undone if you once forget that the fruits of the earth belong to us all, and the earth itself to nobody.


  • Brynnie
  • Registratie: Februari 2001
  • Niet online
Ik heb het met de haakjes op jouw manier geprobeerd, en toch toont de query dan alle "64 MB" waardes en alle "EDO RAM" waardes, ongeacht de andere waardes.

Dus ook bvb records zoals deze:

741258 - 12 - SD RAM
741258 - 15 - 64 MB

alhoewel deze niet getoond mogen worden...

Verwijderd

Kan je eens de code van de query laten zien?

  • Basszje
  • Registratie: Augustus 2000
  • Laatst online: 17:07

Basszje

Reisvaap!]

Ik heb het net met Access geprobeerd ( mijn manier dus :) ) en het grappige is ,dat ik met jou bovenstaande voorbeeldje ( die records ) , ik gewoon 4 records terugkrijg.

Nl 12 - EDO (2x),
15 - 64 MB (2x).

Wat dus klopt

Beware of listening to the imposter; you are undone if you once forget that the fruits of the earth belong to us all, and the earth itself to nobody.


  • Brynnie
  • Registratie: Februari 2001
  • Niet online
SELECT ProductKenmerken.*
FROM ProductKenmerken
WHERE (ProductKenmerken.CatKenID=12 AND ProductKenmerken.Waarde="EDO RAM") OR (ProductKenmerken.CatKenID=15 AND ProductKenmerken.Waarde=" 64")

  • Brynnie
  • Registratie: Februari 2001
  • Niet online
Op maandag 10 september 2001 13:16 schreef BaSSzje het volgende:
Ik heb het net met Access geprobeerd ( mijn manier dus :) ) en het grappige is ,dat ik met jou bovenstaande voorbeeldje ( die records ) , ik gewoon 4 records terugkrijg.

Nl 12 - EDO (2x),
15 - 64 MB (2x).

Wat dus klopt
Maar voeg eens deze records toe en probeer het nog eens:

123547 - 12 - EDO RAM
123547 - 15 - 128 MB

Dan krijg je ook 1x record 123547 te zien, en dat klopt niet.

  • justmental
  • Registratie: April 2000
  • Niet online

justmental

my heart, the beat

De probleemstelling is een beetje vaag, maar het lijkt erop dat je de tabel zou moeten joinen met zichzelf.
Dit omdat je voorwaarden over twee records gaan.

Who is John Galt?


  • Brynnie
  • Registratie: Februari 2001
  • Niet online
Ik weet dat het probleem "vaag" is, maar het valt moeilijk uit te leggen.

In het voorbeeld zijn er twee "voorwaarden", maar dat kunnen er ook meer zijn.

Dus de oplossing van BaSSzje is bruikbaar, maar dan moet je nadien wel kijken welke records in de query zoveel keer voorkomen, als er voorwaarden waren (dus records die aan alle voorwaarden voldoen), en die records zijn dan de correcte...

  • justmental
  • Registratie: April 2000
  • Niet online

justmental

my heart, the beat

Op maandag 10 september 2001 13:37 schreef Brynnie het volgende:
Ik weet dat het probleem "vaag" is, maar het valt moeilijk uit te leggen.

In het voorbeeld zijn er twee "voorwaarden", maar dat kunnen er ook meer zijn.

Dus de oplossing van BaSSzje is bruikbaar, maar dan moet je nadien wel kijken welke records in de query zoveel keer voorkomen, als er voorwaarden waren (dus records die aan alle voorwaarden voldoen), en die records zijn dan de correcte...
Schrijf de resultaatset anders eens uit.
Dus hoe de output van jouw query eruit zou moeten zien met de gegeven input.

Who is John Galt?


  • Crazy D
  • Registratie: Augustus 2000
  • Laatst online: 12:02

Crazy D

I think we should take a look.

Op maandag 10 september 2001 13:37 schreef Brynnie het volgende:
Ik weet dat het probleem "vaag" is, maar het valt moeilijk uit te leggen.
Behoorlijk vaag ja :P
In het voorbeeld zijn er twee "voorwaarden", maar dat kunnen er ook meer zijn.

Dus de oplossing van BaSSzje is bruikbaar, maar dan moet je nadien wel kijken welke records in de query zoveel keer voorkomen, als er voorwaarden waren (dus records die aan alle voorwaarden voldoen), en die records zijn dan de correcte...
En dat maakt het er ook niet duidelijker op :P

Met in je 1e post genoemde waardes, wat moet je resultaat zijn? En in welke volgorde moet dat resultaat zijn?

Exact expert nodig?


  • Brynnie
  • Registratie: Februari 2001
  • Niet online
Tabel:

PID - CatKenID - Waarde

6789 - 12 - EDO RAM
6789 - 15 - 64 MB
4527 - 12 - DDR RAM
4527 - 15 - 32 MB
6544 - 12 - EDO RAM
6544 - 15 - 64 MB
741258 - 12 - SD RAM
741258 - 15 - 64 MB
123 - 12 - EDO RAM
123 - 15 - 32 MB

In dit geval moet met de voorwaarden

waar CatKenID = 12 moet Waarde = "EDO RAM" zijn,
en waar CatKenID = 15 moet Waarde = "64 MB" zijn.

Dus de PID's

6789
6544

moeten als resultaat getoond worden.

Het aantal "voorwaarden" is niet "vast". De ene keer kunnen dat er 2 zijn, de andere keer 3 of meer, of 1. (Dat hangt af van de input die binnenkomt van een form, op een ASP pagina genereer ik dan de juiste SQL code om een recordset aan te maken die de juiste records (dia aan alle voorwaarden voldoen) teruggeeft. Bovenstaande tabel is dus een afgeslankt voorbeeld. Elk PID heetf meer "eigenschappen" dan die die in het voorbeeld vermeld worden. (Een record in die tabel is een weergave van PID - Eigenschap ID en z'n waarde).

Verwijderd

Misschien toch eens nadenken of het design van je tabel(len) ?

Als je van te voren weet det je twee voorwaarden wilt vergelijken :

SELECT PID
FROM tabel tabel1
INNER JOIN tabel tabel2 ON
tabel1.PID = tabel2.PID AND
CatKenID = "voorwaarde2"
Waarde = "voorwaarde2"
WHERE
CatKenID = "voorwaarde1"
Waarde = "voorwaarde1"

  • Crazy D
  • Registratie: Augustus 2000
  • Laatst online: 12:02

Crazy D

I think we should take a look.

Op maandag 10 september 2001 13:46 schreef Brynnie het volgende:
Tabel:

PID - CatKenID - Waarde

6789 - 12 - EDO RAM
6789 - 15 - 64 MB
4527 - 12 - DDR RAM
4527 - 15 - 32 MB
6544 - 12 - EDO RAM
6544 - 15 - 64 MB
741258 - 12 - SD RAM
741258 - 15 - 64 MB
123 - 12 - EDO RAM
123 - 15 - 32 MB

In dit geval moet met de voorwaarden

waar CatKenID = 12 moet Waarde = "EDO RAM" zijn,
en waar CatKenID = 15 moet Waarde = "64 MB" zijn.

Dus de PID's

6789
6544
Uhhmm uit het hoofdje...
SELECT PID
From Tabelletje
WHERE (CatKenID=12 AND Waarde='EDO RAM') OR (CatKenID=15 And Waarde='64 MB')
GROUP BY PID

Zoiets zou het moeten zijn.

Exact expert nodig?


  • Brynnie
  • Registratie: Februari 2001
  • Niet online
Nope, werkt niet, want dan worden ook de PID's van bvb 64 MB DDR RAM getoond...

Dit moet toch "te doen" zijn in SQL?

  • Crazy D
  • Registratie: Augustus 2000
  • Laatst online: 12:02

Crazy D

I think we should take a look.

Op maandag 10 september 2001 14:47 schreef Brynnie het volgende:
Nope, werkt niet, want dan worden ook de PID's van bvb 64 MB DDR RAM getoond...

Dit moet toch "te doen" zijn in SQL?
Nu kan het zijn dat m'n bril vies is hoor, maarre....
PID - CatKenID - Waarde

6789 - 12 - EDO RAM
6789 - 15 - 64 MB
4527 - 12 - DDR RAM
4527 - 15 - 32 MB
6544 - 12 - EDO RAM
6544 - 15 - 64 MB
741258 - 12 - SD RAM
741258 - 15 - 64 MB
123 - 12 - EDO RAM
123 - 15 - 32 MB
Ze hebben allebei hetzelfde PID dus is het logisch dat je 'm dan krijgt, aangezien de voorwaarde aangeeft dat ie CatKen15 - 64 MB moet selecteren. Dat 12 - EDO RAM toevallig hetzelde PID heeft is een kwestie van 'shit happens' :P (klinkt minder negatief dan brak database design ;))
En of het een probleem is, is afhankelijk van wat je verder gaat doen met het resultaat.
Als je met alleen die PID verder gaat werken om een record op te halen, kom je idd in de problemen (maar dat kom je per definitie omdat de unique key zo te zien ligt op PID en CatKenID.

Exact expert nodig?


  • Brynnie
  • Registratie: Februari 2001
  • Niet online
In jouw geval wordt inderdaad dat record getoond, maar OOK alle andere records die slechts aan één van de voorwaarden voldoen.

Nu wou ik dat oplossen door vervolgens door het op PID gesorteerde resultaat te loopen en alles wat evenveel keer voorkomt als er voorwaarden zijn (dus alle PID's die aan alle voorwaarden voldoen) in een array te stoppen om verder op de ASP pagina te gebruiken. MAAR... (Vraag me niet waarom!): Als er meer dan 2 voorwaarden zijn, dan wordt een PID dat toch aan alle voorwaarden voldoet, toch slechts 2x getoond... :?

Het is misschien duidelijker als je snel een klein Access dbase maakt en het daar eens in uitprobeert.

Bvb:

Tabel:
PID - CatKenID - Waarde

6789 - 12 - EDO RAM
6789 - 15 - 64 MB
6789 - 17 - 66 MHz
4527 - 12 - DDR RAM
4527 - 15 - 32 MB
4527 - 17 - 266 MHz
6544 - 12 - EDO RAM
6544 - 15 - 64 MB
6544 - 17 - 66 MHz
741258 - 12 - SD RAM
741258 - 15 - 64 MB
741258 - 17 - 133 MHz
123 - 12 - EDO RAM
123 - 15 - 32 MB
123 - 17 - 66 MHz

En laat daar je queries eens op los...

(PID - CatKenID is idd een unieke sleutel)

Verwijderd

Op maandag 10 september 2001 13:54 schreef r-e-m het volgende:

SELECT PID
FROM tabel tabel1
INNER JOIN tabel tabel2 ON
tabel1.PID = tabel2.PID AND
CatKenID = "voorwaarde2"
Waarde = "voorwaarde2"
WHERE
CatKenID = "voorwaarde1"
Waarde = "voorwaarde1"
Heb je dit al geprobeerd ?

  • Basszje
  • Registratie: Augustus 2000
  • Laatst online: 17:07

Basszje

Reisvaap!]

Op maandag 10 september 2001 14:47 schreef Brynnie het volgende:
Nope, werkt niet, want dan worden ook de PID's van bvb 64 MB DDR RAM getoond...

Dit moet toch "te doen" zijn in SQL?
Wat ook zou kunnen is dat de database een text-based search als een like query ziet.
Immer 64 MB DDR RAM lijkt erop.

Ik stel trouwens voor (ook in het belang van effectieve databases en effiency etc ) dat je ook van die RAM codes een tabel maakt met een unieke id ( een getal ) .
Dat voorkomt een hoop gezeur en gaat een stuk sneller.
kan je ook gewoon op die ID querien ipv moeilijk te doen.

Beware of listening to the imposter; you are undone if you once forget that the fruits of the earth belong to us all, and the earth itself to nobody.


  • Brynnie
  • Registratie: Februari 2001
  • Niet online
Op maandag 10 september 2001 16:02 schreef r-e-m het volgende:

[..]

Heb je dit al geprobeerd ?
Dat is toch geen correcte SQL? (Ik gebruik MS SQL, geen mySQL)

  • Killemov
  • Registratie: Januari 2000
  • Laatst online: 11-09 10:38

Killemov

Ik zoek nog een mooi icooi =)

Als het aantal voorwaarden dynamisch is, dan is je query dat dus automatisch ook. Maar ik denk dat ik begrijp wat je bedoelt, als je bedoelt wat ik begrijp. :?

Het ligt dus niet aan je query ... maar aan je datamodel! Je hebt geprobeerd in een vlaag van optimalisatiedrift alle velden van je tabel uit elkaar te trekken. Dat kan op zich wel, alleen maakt dat het weer bij elkaar rapen/zoeken bijzonder lastig. Je KenCatID is dus eigenlijk het kolomnummer en zo wil je dat dus ook gebruiken.
Als je dit nu toch wil doen, zul je gebruik moeten maken van een scripttaal en geneste queries en je moet dan uit je binnengekomen html-post/get de juiste waarden voor de juiste velden peuteren. (voorbeeld: een inputveld met het KenCatID als naam.)

Ik wens je hiermee echt veel success, want dit blijft lastig.

Hey ... maar dan heb je ook wat!


  • Crazy D
  • Registratie: Augustus 2000
  • Laatst online: 12:02

Crazy D

I think we should take a look.

Op maandag 10 september 2001 16:29 schreef Killemov het volgende:
Als het aantal voorwaarden dynamisch is, dan is je query dat dus automatisch ook. Maar ik denk dat ik begrijp wat je bedoelt, als je bedoelt wat ik begrijp. :?
Durf duidelijke taal te vragen :P
Maar dat je query dynamich is is geen probleem. Het probleem is dat je PID niet uniek is, en je dus PID's terugkrijgt die zowel voor het juiste artikel gelden, als voor een ander produkt met een andere cat-dingesID, maar die wel een zelfde PID heeft...
Het ligt dus niet aan je query ... maar aan je datamodel! Je hebt geprobeerd in een vlaag van optimalisatiedrift alle velden van je tabel uit elkaar te trekken.
IMHO is het enigste probleem dat het artikel geen uniek nummer heeft, maar dat de uniekheid ligt op de id-category combinatie. En da's IMHO (en zo te zien niet alleen die van mij ;)) gewoon niet goed.

Maja er zal wel een reden zijn waarom je het zo hebt opgebouwt, da's natuurlijk lastig bepalen a.d.h. van een tabelletje, maar ik zou beginnen met ervoor te zorgen dat het ID gewoon per definitie uniek is, scheelt je een hoop vaag denkwerk :) Dan kun je gewoon het id query-en en krijg je ook alleen die id's terug die je wilt.
Of zoiets... ;) Uitleggen kan ik beter aan anderen overlaten geloof ik... :)

Exact expert nodig?


  • Brynnie
  • Registratie: Februari 2001
  • Niet online
Op maandag 10 september 2001 16:03 schreef BaSSzje het volgende:

[..]

Wat ook zou kunnen is dat de database een text-based search als een like query ziet.
Immer 64 MB DDR RAM lijkt erop.

Ik stel trouwens voor (ook in het belang van effectieve databases en effiency etc ) dat je ook van die RAM codes een tabel maakt met een unieke id ( een getal ) .
Dat voorkomt een hoop gezeur en gaat een stuk sneller.
kan je ook gewoon op die ID querien ipv moeilijk te doen.
Ik doe toch geen tekst based query?

Die RAM codes zijn maar een voorbeeld. Dit is een onderdeel van een groter project voor een online winkel, die niet alleen RAM maar ook tal van andere zaken verkoopt. Voor elke mogelijke combinatie van mogelijke eigenschappen van een product een tabel maken, is geen optie.

Alle producten zitten netjes in een tabel en hebben oa een categoryid.

Er is dus een category tabel met unieke ID's.

In een andere tabel wordt bepaald welke eigenschappen (hebben elk een uniek ID) voor die vategorie dienen bijgehouden te worden. (zoals voor geheugen: Bussnelheid, type en capaciteit).

ID - CategoryID - Eigenschap - Eenheid
12 - 10 - Soort - ''
15 - 10 - Capaciteit - 'MB'
17 - 10 - Bussnelheid - 'MHz'

10 is hier dus het categoryid.

In een andere tabel wordt per artikel elke nodige eigenschap vastgelegd. (Da's de tabel waar we nu dus mee werken)

In die tabel kan dus verschillende malen hetzelfde PID zitten, telkens met een ander CatKenID (eigenschapsid).

(Een PID of ProductID is uniek per product, maar per product kunne vreschillende eigenschappen vastgelegd zijn, vandaar dat een PID verschillende malen kan voorkomen (met een ander CatKenID of CategoryKenmerkID) in die "eigenschappentabel")

Nu moet een SQL query uit die tabel PID's halen, gebasserd op eender welke combinatie (en aantal) gestelde voorwaarden.

Een gebruiker zal dus kunnen zeggen: "Toon mij alle DDR RAM" of ook "Toon mij alle SDRAM waarvan de bussnelheid 133 MHz is". En zo voorts.

Maar aangezien dat dit voor alle producten zo is, zal de gebruiker ook kunnen zeggen "Toon mij alle hard disks van 30 GB of groter, met 7200 rpm".

Dus moeten we een query maken die aan de hand van de gegeven tabel alle records die aan ALLE gestelde voorwaarden voldoen, eruit haalt.

Volgens mij is het database design goed, maar is het enkel een kwestie van de juiste query samen te stellen.

  • Crazy D
  • Registratie: Augustus 2000
  • Laatst online: 12:02

Crazy D

I think we should take a look.

Op maandag 10 september 2001 16:39 schreef Brynnie een stukje tekst die de boel een stuk duidelijker maakt
Alleen snap ik niet wat er dan mis is met de eerdere query. Die geeft immers een lijstje van PID's die dat betreffende kenmerk hebben. Alleen moet het dan niet Or zijn, maar overal And.
(catkenid=12 AND waarde='EDO RAM') and (catkenid=15 AND waarde='64 mb')

Volgende keer graag in je 1e post iets meer uitleg geven, voorkomt een hoop vaagheden ;)

Exact expert nodig?


  • Brynnie
  • Registratie: Februari 2001
  • Niet online
Die query klopt niet.

Probeer het zelf eens uit op deze pagina:
http://www.cybercom.be/testf.asp?cat=6

Je kan de eigenschappen selecteren en nadat je op submit klikt, zie je het resultaat en het sql statement dat gegenereert werd.

  • Crazy D
  • Registratie: Augustus 2000
  • Laatst online: 12:02

Crazy D

I think we should take a look.

Ok wacht ff, ik denk dat ik begrijp wat je bedoelt (alleen nu nog ff onder woorden brengen ;)), maar heb effies iets meer info nodig... ;)

SQL 7 zei je?
Als je wilt, gooi de database ff ergens online, attach ik 'm hier ff en ga ff vogelen (beter dan het saaie werk wat ik eigenlijk vanavond zou moeten doen ;)).

Exact expert nodig?


  • Brynnie
  • Registratie: Februari 2001
  • Niet online
Kan de database niet online gooien, want het is een bedrijfsdatabase, en ik heb de rechten er niet toe...

Kan je het toch proberen? Ik breek er al een hele dag m'n kop over! :'(

Verwijderd

select *
from tbl_bla
having ( CatkenID = 12 and waarde="edo" )
or ( CatkenID = 15 and waarde = "64" )

  • Brynnie
  • Registratie: Februari 2001
  • Niet online
Je kan geen having component gebruiken zonder dat je groepering of aggregatie gebruikt.

  • Crazy D
  • Registratie: Augustus 2000
  • Laatst online: 12:02

Crazy D

I think we should take a look.

Op maandag 10 september 2001 23:53 schreef Brynnie het volgende:
Kan de database niet online gooien, want het is een bedrijfsdatabase, en ik heb de rechten er niet toe...
Ok, post (of mail) anders ff een stukje echte data, zeg maar de items zoals ze op die testpagina staat zoals ze bij jou in de db staan (incl een paar items uit je artikel tabel zodat die link te leggen is ed.)

PS
met deze data
code:
1
2
3
4
5
6
7
PID    CatKenID  Waarde
4527   12     DDR RAM
4527   15     32 MB
6544   12     EDO RAM
6544   15     EDO RAM
6789   12     EDO RAM
6789   15     64 MB

Geeft deze query:
code:
1
2
3
4
5
SELECT Tabel.PID, Tabel.CatKenID
FROM Tabel
WHERE (CatKenID=12 AND Waarde='EDO RAM') OR 
    (Tabel.CatKenID=15 AND Tabel.Waarde='64 MB')
GROUP BY Tabel.PID, Tabel.CatKenID;

Dit als resultaat:
code:
1
2
3
4
PID     CatKenID
6544    12
6789    12
6789    15

Wat imho ook klopt. In de query vraag ik om alles waarbij catkenid 12 is met de waarde EDO RAM. Dat zijn 6544 en 6789.
Daarnaast vraag ik ook om vatkenid 15 met waarde 64 mb. Da's ook de 6789.
Hmm en nu zou het resultaat dus eigenlijk moeten zijn, alleen PID 6789 ? Begrijp ik het dan eindelijk goed? (in dat geval klopt de query idd niet zelfs niet met de testdata hier)

Exact expert nodig?


  • XiaZz
  • Registratie: Oktober 2000
  • Laatst online: 19-09 23:02
code:
1
2
3
4
5
6
7
8
9
SELECT tbl1.field1, tbl1.Field2, tbl1.Field3
FROM table1 tbl1
WHERE (tbl1.field2="12") AND
     tbl1.field1 IN (
                 SELECT tbl2.field1
                 FROM table1 tbl2
                 WHERE(tbl2.field2="15") AND
                     (tbl2.field3="64 MB")
                 )

  • Crazy D
  • Registratie: Augustus 2000
  • Laatst online: 12:02

Crazy D

I think we should take a look.

Ok nog ff gehobbied... :)
code:
1
2
3
4
5
6
7
8
SELECT p.* FROM ProduktKenmerken p
WHERE p.PID IN (
    SELECT pk.PID
    FROM ProduktKenmerken pk
    WHERE (pk.CatKenID=15 And pk.Waarde='64 MB') OR 
          (pk.CatKenID=12 AND pk.Waarde='EDO RAM')
    ) 
    AND (p.CatKenID=15 And p.Waarde='64 MB')

De subqeury geeft alles terug waarbij 1 van de 2 voorwaardes klopt. In mijn testdb 4527, 6544 en 6789.
De extra AND daarna is om dat resultaat weer te filteren. Daarna is m'n resultaat 6789. En da's toevallig ook de enigste PID in m'n db die bij catkenid 15 64 MB heeft staan, en catkenid 12 de waarde EDO RAM.
Hope this helps :)

En dan is het nu tijd om eens wat voor m'n baas te gaan doen :)

Exact expert nodig?


  • Brynnie
  • Registratie: Februari 2001
  • Niet online
Op dinsdag 11 september 2001 10:25 schreef XiaZz het volgende:
code:
1
2
3
4
5
6
7
8
9
SELECT tbl1.field1, tbl1.Field2, tbl1.Field3
FROM table1 tbl1
WHERE (tbl1.field2="12") AND
     tbl1.field1 IN (
                 SELECT tbl2.field1
                 FROM table1 tbl2
                 WHERE(tbl2.field2="15") AND
                     (tbl2.field3="64 MB")
                 )
Je kan geen geneste selects gebruiken, omdat het aantal voorwaarden (en dus bijgevolg geneste selects) dynamisch is. In dit voorbeeld zijn dat er twee, maar dat kunnen er (extreem) ook bvb 10 zijn.
Op dinsdag 11 september 2001 10:15 schreef CrazyD_at_work het volgende:

[..]

Ok, post (of mail) anders ff een stukje echte data, zeg maar de items zoals ze op die testpagina staat zoals ze bij jou in de db staan (incl een paar items uit je artikel tabel zodat die link te leggen is ed.)

PS
met deze data
code:
1
2
3
4
5
6
7
PID    CatKenID  Waarde
4527   12     DDR RAM
4527   15     32 MB
6544   12     EDO RAM
6544   15     EDO RAM
6789   12     EDO RAM
6789   15     64 MB

Geeft deze query:
code:
1
2
3
4
5
SELECT Tabel.PID, Tabel.CatKenID
FROM Tabel
WHERE (CatKenID=12 AND Waarde='EDO RAM') OR 
    (Tabel.CatKenID=15 AND Tabel.Waarde='64 MB')
GROUP BY Tabel.PID, Tabel.CatKenID;

Dit als resultaat:
code:
1
2
3
4
PID     CatKenID
6544    12
6789    12
6789    15

Wat imho ook klopt. In de query vraag ik om alles waarbij catkenid 12 is met de waarde EDO RAM. Dat zijn 6544 en 6789.
Daarnaast vraag ik ook om vatkenid 15 met waarde 64 mb. Da's ook de 6789.
Hmm en nu zou het resultaat dus eigenlijk moeten zijn, alleen PID 6789 ? Begrijp ik het dan eindelijk goed? (in dat geval klopt de query idd niet zelfs niet met de testdata hier)
In je testdata klopt iets niet:
code:
1
2
3
4
5
6
7
PID    CatKenID  Waarde
4527   12     DDR RAM
4527   15     32 MB
6544   12     EDO RAM
6544   15     EDO RAM
6789   12     EDO RAM
6789   15     64 MB

CatKenID 15 van PID 6544 moet een capaciteit zijn.

In jouw geval moet de query dus idd enkel pid 6789 terugkeren.

Een stukje echte data:

Heb een Access file gemaakt (180 kB) met daarin de nodige data. Kan hem als je wil naar het e-mail adres uit je profiel mailen...

  • Brynnie
  • Registratie: Februari 2001
  • Niet online
Op dinsdag 11 september 2001 10:49 schreef CrazyD_at_work het volgende:
Ok nog ff gehobbied... :)
code:
1
2
3
4
5
6
7
8
SELECT p.* FROM ProduktKenmerken p
WHERE p.PID IN (
    SELECT pk.PID
    FROM ProduktKenmerken pk
    WHERE (pk.CatKenID=15 And pk.Waarde='64 MB') OR 
          (pk.CatKenID=12 AND pk.Waarde='EDO RAM')
    ) 
    AND (p.CatKenID=15 And p.Waarde='64 MB')

De subqeury geeft alles terug waarbij 1 van de 2 voorwaardes klopt. In mijn testdb 4527, 6544 en 6789.
De extra AND daarna is om dat resultaat weer te filteren. Daarna is m'n resultaat 6789. En da's toevallig ook de enigste PID in m'n db die bij catkenid 15 64 MB heeft staan, en catkenid 12 de waarde EDO RAM.
Hope this helps :)

En dan is het nu tijd om eens wat voor m'n baas te gaan doen :)
Met die query en mijn test data krijg ik in mijn Access test dbase een ODBC error terug (Incorrect syntax near FROM) en in de echte SQL 7 dbase krijg ik alle PIDs van geheugen met capaciteit 64 MB, dus niet enkel het EDO RAM zoals zou moeten...

  • Crazy D
  • Registratie: Augustus 2000
  • Laatst online: 12:02

Crazy D

I think we should take a look.

Ok mail maar ff naar m'n profiel (:?) dan pomp ik die data wel ff over in SQL.
Had trouwens die aanpassing in m'n SQL db wel gemaakt (CatKenID 15 van PID 6544 moet een capaciteit zijn)

Maar ik blijf het vaag vinden dat ie niet de juiste waardes teruggeeft.

Als je redeneert wat ie doet...
SELECTEER alles
UIT Tabelletje
WAARBIJ PID VOORKOMT IN
(
haal alles op waarbij 1 van de voorwaardes klopt
)
EN extra-voorwaarde.
Waarbij extra-voorwaarde de uhmm hoe zeg je dat, meest significante voorwaarde(s) staan (da's niet mijn normale spreektaal :+) Waarbij in dit geval de 64 MB mij wel essentieel lijkt...

Zet in je mailtje ook ff wat bij bepaalde voorwaardes de uitkomst moet zijn, en wat als 1 van de gegevens niet klopt (bv EDO RAM 256 MB, als je die niet hebt, wat ie dan moet teruggeven)
Alles beter dan het saaie werk wat ik eigenlijk moet doen vandaag, en sql queries is wel leuk om te maken :) (en goed voor kennis/ervaring :))

Exact expert nodig?


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 21-09 13:51

Janoz

Moderator Devschuur®

!litemod

Waarom proberen mensen een slecht datamodel toch altijd weer af te vangen met super ingewikkelde queries!!

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Brynnie
  • Registratie: Februari 2001
  • Niet online
Mail is verstuurd naar het e-mail adres dat in je profiel staat.

Als je voorwaarden stelt waarvoor een geen producten zijn, dan moet de query niks tonen.
Op dinsdag 11 september 2001 11:13 schreef Janoz het volgende:
Waarom proberen mensen een slecht datamodel toch altijd weer af te vangen met super ingewikkelde queries!!
Als je de hele thread zou lezen, dan zou je zien dat het datamodel (naar mijn mening) behoorlijk goed is. Dit is enkel een moeilijk naar SQL om te zetten "vraag aan de database".

Verwijderd

Op maandag 10 september 2001 16:26 schreef Brynnie het volgende:

[..]

Dat is toch geen correcte SQL? (Ik gebruik MS SQL, geen mySQL)
Ik dacht het toch wel. Ik gebruik namelijk ook SQL7.

Ook ik heb even zitten hobbien
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
create table TestTbl 
(
PID [int],
CatKenID [int],
Waarde varchar(10)
)

insert into TestTbl(PID,CatKenID,Waarde) VALUES (4527, 12, 'DDR RAM')
insert into TestTbl(PID,CatKenID,Waarde) VALUES (4527, 15, '32 MB')
insert into TestTbl(PID,CatKenID,Waarde) VALUES (6544, 12, 'EDO RAM')
insert into TestTbl(PID,CatKenID,Waarde) VALUES (6544, 15, '32 MB')
insert into TestTbl(PID,CatKenID,Waarde) VALUES (6789, 12, 'EDO RAM')
insert into TestTbl(PID,CatKenID,Waarde) VALUES (6789, 15, '64 MB')

select Tbl.PID from TestTbl Tbl
INNER JOIN TestTbl Tbl2 ON
    Tbl.PID = Tbl2.PID AND
    (Tbl2.CatKenID = 15) AND
    (Tbl2.Waarde = '32 MB')
WHERE
    (Tbl.CatKenID = 12) AND
    (Tbl.Waarde = 'DDR RAM')

Dit geeft als resultaat een PID van 4527.

Omdat het aantal waarden die je wilt vergelijken dynamisch is zul je query ook dynamisch moeten opbouwen...

  • Brynnie
  • Registratie: Februari 2001
  • Niet online
Ja, dit lijkt inderdaad te werken.

Maar ik snap de query niet 100%. Kan je eens een voorbeeldje geven van hoe de query er zou uitzien wanneer er bvb 3 of 4 voorwaarden zijn?

[edit]

Ik heb het systeem door, maar een heel erg groot nadeel aan die query is dat hij bij bvb 3 voorwaarden heel erg lang duurt.

In het voorbeeld misschien niet, maar op de SQL server, met 1000-en producten met elk hun eigen eigenschappen duurt de query met drie voorwaarden al snel enkele seconden, wat voor gebruik op een webpagina niet optimaal is...

De query mag bvb ook alle producten tonen waarvoor één van de voorwaarden waar is, dan kan ik met behulp van een array alle producten eruit halen die evenveel keer voorkomen als er voorwaarden zijn (dus alle producten die aan alle voorwaarden voldoen). Naar mijn mening zou deze aanpak sneller moeten verlopen dan een join query.

  • Crazy D
  • Registratie: Augustus 2000
  • Laatst online: 12:02

Crazy D

I think we should take a look.

Inner join is denk ik the way to go...
code:
1
2
3
4
5
6
7
8
9
SELECT kp1.ProductID from KenmerkenProd kp1
INNER JOIN KenmerkenProd kp2 ON
    kp1.ProductID = kp2.ProductID AND
    (kp2.KenCatID = 45 And kp2.Waarde = '512')
INNER JOIN KenmerkenProd kp3 ON
    kp1.ProductID = kp3.ProductID AND
    (kp3.KenCatID = 43 And kp3.Waarde = '133')
WHERE
    (kp1.KenCatID = 42 And kp1.Waarde = 'SDRAM')

Dit geeft ProductID 2312, en laat dat nou net het juiste artikel zijn :)

Als je 'm ff test met diverse waardes kan ik weer even wat doen waarvoor ik betaald wordt :( (niet vanwege het betaald worden maar vanwege hetgeen wat ik vandaag moet doen...) dan horen we zo wel weer verder ;)
Je zal dus per voorwaarde een inner join er tegenaan moeten gooien, misschien niet superefficient maar 't werkt wel ;)

En zo slecht is je datamodel idd niet ;) Ik denk dat ik 'm hetzelfde had opgezet (naja niet dat het dan ineens goed is of zo ;))

[edit]
ejj niet stiekum editten terwijl ik zit te posten :P
Ik denk dat het sneller/efficienter is om MSSQL het werk te laten doen, dan dat jezelf met arrays gaat werken.
Misschien kun je iets met een stored procedure verzinnen?

Exact expert nodig?


Verwijderd

*misschien overbodige opmerking*


Voor de snelheid:
index over PID en een index over CatKenID, Waarde

  • Brynnie
  • Registratie: Februari 2001
  • Niet online
Heb de ASP loop die de query maakt voor elkaar gekregen.

Nu werkt de query wel snel genoeg. Wat ik heb gewijzigd:

Eerst haalde de query zijn productIDs uit een andere query die reeds alle productinfo (zoals fabrikant, prijzen en dergelijke) bevatte. Maar doordat die andere query dus eerst moest lopen, duurde het allemaal uiteindelijk veel te lang.

Nu haalt de query die we hier op punt gesteld hebben z'n gegevens uit de tabel met producteigenschappen, en daarna haal ik voor alle productIDs die voldoen aan alle voorwaarden dus rest van de productinfo uit de SQL server (dank zij het unieke productid). Zo hoef ik slechts de volledige productinformatie op te vragen van de producten die ik echt nodig heb en moet weergeven, en niet van alle producten.

Het ziet ernaar uit dat dit eindelijk werkt...

Bedankt aan iedereen die direct of indirect heeft meegeholpen tot het bekomen van de oplossing!

Nu kan CrazyD_at_work z'n baas eindelijk laten zien waarom hij elke maand zoveel zakken geld naar huis mag slepen. ;)

Dit was het voorlopig vanuit het ASP SQL sprookjesbos, tot een volgende keer!

  • Tsjipmanz
  • Registratie: Oktober 2000
  • Laatst online: 13-05 14:52

Tsjipmanz

Der Rudi ist da

Op dinsdag 11 september 2001 11:17 schreef Brynnie het volgende:

Als je de hele thread zou lezen, dan zou je zien dat het datamodel (naar mijn mening) behoorlijk goed is. Dit is enkel een moeilijk naar SQL om te zetten "vraag aan de database".
Janoz heeft gelijk, het is een slecht datamodel en het bespaart nauwelijks ruimte.
Een datamodel dat naar MIJN mening "goed" is, is een datamodel waarbij de queries eenvoudig te construeren zijn EN gemakkelijk leesbaar zijn.

There's no such thing as a mistake, just happy accidents - Bob Ross
Relaxte muziek: altijd okee!
- Soulseek rulez -


  • tomato
  • Registratie: November 1999
  • Niet online
Op dinsdag 11 september 2001 12:45 schreef Tsjipmanz het volgende:
Een datamodel dat naar MIJN mening "goed" is, is een datamodel waarbij de queries eenvoudig te construeren zijn EN gemakkelijk leesbaar zijn.
Hmmmm, dan hoop ik dat ik nooit met een datamodel van jou te maken krijg. In de eerste plaats moet je juist geen rekening houden met de queries die je nodig hebt om bepaalde informatie uit je gegevens te halen. Om het dan uiteindelijk 'bruikbaar' te maken kan het zijn dat je op dit punt nog wat aanpassingen wilt doen aan je model, maar liever niet. 'Goed' is overigens ook nogal een erg vaag begrip.

  • Brynnie
  • Registratie: Februari 2001
  • Niet online
Een goed datamodel is volgens mij een datamodel waar je zo weinig mogelijk informatie dubbel opslaat. Je werkt dus zoveel mogelijk genormaliseerd en zorgt ervoor dat je aan de hand van indices en id's snel en makkelijk data kan koppelen.

Akkoord, in sommige gevallen, zoals bovenstaand voorbeeld illustreert, is het soms zwoegen om een correcte query samen te stellen, maar dat werk weegt niet op tegen het gemak van de handelbaarheid en uitbreidbaarheid van de database in z'n geheel.

  • Crazy D
  • Registratie: Augustus 2000
  • Laatst online: 12:02

Crazy D

I think we should take a look.

Gezien dat er een aantal reacties zijn waarin het datamodel slecht wordt genoemd, misschien leuk om even het huidige datamodel (of deel van als er teveel bedrijfsgeheime dingen in voorkomen (?)) neer te zetten, en dan de mensen die het slecht vinden laten aangeven waarom het slecht is en wat zij zouden veranderen?
Ik ben nl. wel benieuwd naar wat 'men' slecht vind in dit datamodel. Ok de query wordt er niet makkelijker op, maar ik vind 't stukje wat ik gemaild heb gekregen netjes opgezet (= zo zou ik het ook doen, dus imho niet slecht dus (tenminste, ik maak niet vaak dingen die ikzelf daarna als slecht beoordeel ;)))

Exact expert nodig?


  • Tsjipmanz
  • Registratie: Oktober 2000
  • Laatst online: 13-05 14:52

Tsjipmanz

Der Rudi ist da

Op dinsdag 11 september 2001 14:32 schreef tomato het volgende:

[..]

Hmmmm, dan hoop ik dat ik nooit met een datamodel van jou te maken krijg. In de eerste plaats moet je juist geen rekening houden met de queries die je nodig hebt om bepaalde informatie uit je gegevens te halen. Om het dan uiteindelijk 'bruikbaar' te maken kan het zijn dat je op dit punt nog wat aanpassingen wilt doen aan je model, maar liever niet. 'Goed' is overigens ook nogal een erg vaag begrip.
Het is ook niet het criterium dat je gebruikt om je datamodel te maken, maar de ervaring heeft mij tot nu toe geleerd dat wanneer je een goed datamodel hebt, de queries een stuk gemakkelijker te construeren zijn (dit heeft onder andere te maken met het feit dat je normaal gesproken ook al tijdens het ontwerp rekening houdt met wat je gaat doen met je database en welke transacties op de database uitgevoerd zullen worden).

Als je later nog veel aanpassingen moet doen heb je dus met bepaalde dingen waarschijnlijk niet rekening gehouden en is je ontwerp niet goed.

Maar ja, dat is mijn mening, geen feit.

There's no such thing as a mistake, just happy accidents - Bob Ross
Relaxte muziek: altijd okee!
- Soulseek rulez -


  • Killemov
  • Registratie: Januari 2000
  • Laatst online: 11-09 10:38

Killemov

Ik zoek nog een mooi icooi =)

Op dinsdag 11 september 2001 14:39 schreef Brynnie het volgende:
Een goed datamodel is volgens mij een datamodel waar je zo weinig mogelijk informatie dubbel opslaat. Je werkt dus zoveel mogelijk genormaliseerd ...
Mee eens! En kijk nu een hoeveel keer jij dezelfde PID, CatKenID en Waarde opslaat. Beter: Maak dan een tabel met max(kenkatid) kolommen en zet de waardes die niet van toepassing zijn op null. Best: In principe zijn 'geheugen' en 'processor' specialisaties van 'produkt'. Als je gebruik zou kunnen maken van subtypes, dan is dit een prima voorbeeld van een toepassing daarvan. Je hoofdtabel zou dan 'produkt' zijn (met in ieder geval de naam van het produkt, de prijs en alle andere velden die alle producten met elkaar delen.) en je subtabellen bijvoorbeeld 'prod_geheugen' (MB) of 'prod_processor'. (MHz)
... en zorgt ervoor dat je aan de hand van indices en id's snel en makkelijk data kan koppelen.
Indices en id's zijn vaak toch ook zeker niet de heilige graal hoor.
Akkoord, in sommige gevallen, zoals bovenstaand voorbeeld illustreert, is het soms zwoegen om een correcte query samen te stellen, maar dat werk weegt niet op tegen het gemak van de handelbaarheid en uitbreidbaarheid van de database in z'n geheel.
En wat is er mis met alter table? >:)

Hey ... maar dan heb je ook wat!

Pagina: 1