Toon posts:

[mysql]Velden tellen die niet overeen komen in de join

Pagina: 1
Acties:

Verwijderd

Topicstarter
Mijn probleem, ik heb 2 tabellen welke kan worden gekoppeld met een join. Nu wil ik in 1 query tellen hoe veel velden van tabel 2 niet met tabel 1 overeen komt.

Hierbij een voorbeeld om het probleem duidelijk te maken:
tabel 1:
id data
1 blaat
2 af
3 sdsds
4 as
5 sds

tabel 2:
id iduser
1 1
2 1
3 1

Nu wil ik dus dat ik '2' terug krijg uit de sql query. (omdat id 4 en 5 niet overeen komen).

Ik kan dit probleem natuurlijk oplossen door 2 query's (eerst tabel 1 en dan tabel 2 tellen en dan de 2 getallen van elkaar aftrekken), maar dat duurt te lang. Dit script wordt namelijk straks met een grote regelmaat bezocht. (komt in een login script) De query moet dus ook snel blijven en dat lukt mij dus niet. Ik heb zo een gevoel dat dit probleem makkelijk kan worden opgelost, maar ik kon niets vinden in de faq, google,got of de mysql site. Als iemand mij hiermee kan helpen, graag :) Iedergeval bedankt voor het lezen. :*)

[ Voor 5% gewijzigd door Verwijderd op 07-01-2005 09:41 ]


  • TheRookie
  • Registratie: December 2001
  • Niet online

TheRookie

Nu met R1200RT

Ik neem aan dat je het over twee tabellen hebt, en niet twee databases ?
Dan zou je beide tabellen moeten joinen op ID en dan een count uitvoeren met where iduser is null ?
code:
1
2
3
4
5
6
7
select 
  count(tabel1.*) 
from 
  Tabel1 
  left join Tabel2 on Tabel1.id=Tabel2.id
where
  Tabel2.iduser is null

of iets van die strekking ...

[ Voor 17% gewijzigd door TheRookie op 07-01-2005 09:48 . Reden: typo's :| ]


Verwijderd

Topicstarter
Ja, het is inderdaad tabellen ;) . Evengoed heb ik dit geprobeerd maar ook dit werkt niet. Toch denk ik dat ik het wel in deze richting moet zoeken, maar ik weet het niet precies.

Ook klopte de query niet omdat ik iduser ook moet opgeven dus komt hij al volgt uit (wat natuurlijk nergens op slaat 8)7
code:
1
2
3
4
5
6
7
select 
  count(Tabel2.id) 
from 
  Tabel1 
  left join Tabel2 on Tabel1.id=Tabel2.id
where
  Tabel2.iduser is null AND Tabel2.iduser = 1


Iedergeval bedankt voor je hulp. _/-\o_ Nog meer ideeen?

  • TheRookie
  • Registratie: December 2001
  • Niet online

TheRookie

Nu met R1200RT

waarom moet je IDuser =1 opgeven ?

Verwijderd

Topicstarter
omdat.. wacht.. voorbeeld :)
tabel 1:
id data
1 blaat
2 af
3 sdsds
4 as
5 sds

tabel 2:
id iduser
1 1
2 1
3 1
1 2
2 2
1 3
2 3
3 3
4 3

Zo ziet de tabel er dus uit. Om het wat duidelijker maken zal ik de situatie voorleggen:

Een gebruiker kan dus op dingen klikken. Zodra ze geklikt hebben wordt tabel 2 gevuld met hun id nummer (iduser) en het id van waar ze op geklikt hebben (id). Dan kan ik dus zien of iemand geklikt heeft. Ik wil dus laten zien op hoeveel dingen ze nog niet geklikt op hebben. Dit moet dan in 1 simpele query komen. Nu heb ik een veel ste langzame oplossing door middel van php en dat moet dus vervangen worden door een snelle query. :)

Hopelijk is het zo duidelijk anders hoor ik het graag :Y)

  • TheRookie
  • Registratie: December 2001
  • Niet online

TheRookie

Nu met R1200RT

als je sql versie geen subqueries aan kan lijkt me een count(*) van beide tabellen toch 't snelst...
Een count duurt toch niet zo lang ?

Als je wél subqueries kan gebruiken:
code:
1
2
3
4
5
6
select 
    count(*) as numToClick,
    (Select count(*) from Table2 where IDUser=3) as numClicked,
    count(*) - (Select count(*) from Table2 where IDUser=3) as numToGo
from 
    Table1
should do the trick

[ Voor 58% gewijzigd door TheRookie op 07-01-2005 10:38 . Reden: + subquery voorbeeld ]


Verwijderd

Topicstarter
TheRookie, bedankt. Ik denk niet dat mysql subquery's aan kan eigelijk. (meestal als ik een beetje ingewikkelde dingen wil met mijn database laat mysql mij in de steek).

Kijk het duurt ook niet zo lang. 1 count duurt 0,0007 seconde . Dus 2 counts zal komen op 0,0014 seconde. Alleen omdat dit script regelmatig wordt bezocht en ongeveer 20.000 hits per dag moet verwerken heb ik toch liever de 0,0007 ;) . Ook omdat de database al aardig belast is. Daarom had ik eigelijk gehoopt op een isnotjoin ofzo :P . Maar ik merk al dat dit er niet is, dus ik zal een andere oplossing moeten verzinnen (toch maar 2 query's of subquery's).

TheRookie. Bedankt voor je hulp :Y)

  • TheRookie
  • Registratie: December 2001
  • Niet online

TheRookie

Nu met R1200RT

MySQL versies vanaf (ik meen) 4.1 ondersteunen wel sub-queries ...
de MySQL site geeft ook nog tips voor het omschrijven van subqueries, misschien heb je daar wat aan ?

Verwijderd

Als je DBMS het ondersteunt kan je je toevluht nemen tot queries met
SQL:
1
WHERE EXISTS

  • PhoeniX-
  • Registratie: Juni 2000
  • Laatst online: 29-04 09:11
De mysql docs raden aan om het te doen zoals Tha_Rookie aangeeft (als jouw versie geen subqueries ondersteund). Het is wat gestuntel, maar het werkt wel :)

Hier nog een voorbeeld zoals ik het gebruik, om in dit geval juist de producten zonder categorie op te halen:
SQL:
1
2
3
4
5
SELECT DISTINCT c.id
FROM product c
LEFT JOIN categorie pc
ON c.id = pc.product_id
WHERE pc.product_id IS NULL


edit:
Voorbeeld toegevoegd

[ Voor 49% gewijzigd door PhoeniX- op 07-01-2005 14:56 ]


Verwijderd

Topicstarter
Tja, ik draai mysql 3.2 nog. Ik moet eigelijk deze updaten, maar omdat het een productie server is is dit nogal lastig. (vooral als het fout gaat) .Toch jammer dat het niet zo makkelijk is als ik gehoopt had. Subqueries zijn (helaas) geen oplossing. De eerste oplossing van TheRookie en PhoeniX- zijn opzich het meest logisch en ik denk dat ik dat maar op 1 of andere manier werkend moet krijgen. Goed de vrijdag is nog jong ;) Meteen de mysql handleiding nalezen voor WHERE EXISTS (al hoewel ik hier nog nooit van heb gehoord eigelijk). Ik kom er wel :7

Verwijderd

Topicstarter
Woeii heb het (al hoewel ik het niet een erg snelle oplossing vind maar goed).

Het probleem was de iduser=1 . Toen kwam ik op het volgende idee:

SELECT COUNT(*)
FROM tabel1
LEFT JOIN tabel2 ON ( tabel1.id = tabel2.id
AND tabel2.iduser =1 ) WHERE tabel2.iduser IS NULL

Omdat ik dus dit deed: ( tabel1.id = tabel2.id
AND tabel2.iduser =1 ) inplaats van de iduser in de WHERE te doen geeft hij alles terug van die user en alles wat niet bestaad. Door de IS NULL filter ik alleen de gene uit die niet bestaan. :)

Iedereen bedankt voor de hulp (en vooral TheRookie). _/-\o_
Pagina: 1