[mySQL-php] dubbele results bij join.

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Beste mensen,

Ik heb een probleem met een query, deze geeft namelijk SOMMIGE rijen dubbel weer. En ook nog eens met verkeerde prijzen.
Dit is de query: in PHP

code:
1
2
3
4
5
$q=
SELECT *
FROM  Artikels
LEFT JOIN Price ON Artikels.productID = Price.productID
WHERE Artikels.catID='5000';


De code is enigzins gestript.

Ik krijg nu rijen terug die er bijvoorbeeld als volgt uitzien:

code:
1
2
3
4
5
ID   Naam   Prijs
..............
23  FIETS  345.00 Euro 
23  FIETS  120.00 Euro
..............


Zit er structureel iets mis in de query? Ik kan de bug er niet uitkrijgen. Wil iemand mij hierbij helpen?

[ Voor 5% gewijzigd door Verwijderd op 12-01-2003 23:32 ]


Acties:
  • 0 Henk 'm!

  • rvtk
  • Registratie: Juni 2001
  • Laatst online: 12:30
Dit had ik laatst ook. Ik weet zelf niet meer precies de oplossing, maar je joint verkeerd. Misschien werkt dit beter:

$q=
SELECT *
FROM Artikels
LEFT JOIN Price ON Price.productID = Artikels.productID
WHERE Artikels.catID='5000';

(eventueel opzoeken hoe er ook alweer precies gejoint moet worden zou uitkomst bieden)

[ Voor 19% gewijzigd door rvtk op 13-01-2003 00:49 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Ik denk dat DISTINCT wel iets is wat je kan gebruiken ;)

http://www.mysql.com/doc/en/SELECT.html

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Morgen na mijn werk zal ik de reacties beter bekijken, mijn dank voor de replies tot op heden.

Acties:
  • 0 Henk 'm!

Verwijderd

Verwijderd schreef op 12 January 2003 @ 23:31:
Beste mensen,
...
code:
1
2
3
4
5
$q=
SELECT *
FROM  Artikels
LEFT JOIN Price ON Artikels.productID = Price.productID
WHERE Artikels.catID='5000';


...
Kijk eens naar je FROM: je vergeet de tabel Price!!

Probeer dit eens
code:
1
2
3
4
5
$q=
SELECT *
FROM  Artikels, Price
LEFT JOIN Price ON Artikels.productID = Price.productID
WHERE Artikels.catID='5000';


Zou moeten werken enneh waarom gebruik je bij SELECT het '*', je wil toch niet alle tabellen uit een join :?

[ Voor 18% gewijzigd door Verwijderd op 13-01-2003 00:52 . Reden: typo's in code ]


Acties:
  • 0 Henk 'm!

Verwijderd

Ik denk niet dat distinct zo interessant is, want dat is een workaround.

Wat ik overigens ook niet snap is da je de prijs in een apparte tabel hebt staan, dat is toch een eigenschap van een artikel???

Acties:
  • 0 Henk 'm!

  • rvtk
  • Registratie: Juni 2001
  • Laatst online: 12:30
Verwijderd schreef op 13 januari 2003 @ 00:37:
Ik denk dat DISTINCT wel iets is wat je kan gebruiken ;)

http://www.mysql.com/doc/en/SELECT.html
Je oplossing werkt inderdaad, maar een goede join is naar mijn idee een nettere oplossing.

Acties:
  • 0 Henk 'm!

Verwijderd

rvtk schreef op 13 January 2003 @ 00:51:
[...]


Je oplossing werkt inderdaad, maar een goede join is naar mijn idee een nettere oplossing.
Heb je mijn code al geprobeerd? Ben wel benieuwd of dat de oplossing is...

Acties:
  • 0 Henk 'm!

Verwijderd

rvtk schreef op 12 January 2003 @ 23:47:
$q=
SELECT *
FROM Artikels
LEFT JOIN Price ON Price.productID = Artikels.productID
WHERE Artikels.catID='5000';

...

Je oplossing werkt inderdaad, maar een goede join is naar mijn idee een nettere oplossing.
>> rvtk:

Dat zou in principe weinig mogen uitmaken; verschil a=b of b=a heeft weinig belang, omdat -dachtik- MySQL LEFT JOIN condities als WHERE condities beschouwt. En jah ik weet dat distinct niet de mooiste oplossing is, maar het is hier ook 1 uur 8)

Anyway bokkel zijn oplossing zou toch correcte resultaten moeten opleveren.

Acties:
  • 0 Henk 'm!

  • rvtk
  • Registratie: Juni 2001
  • Laatst online: 12:30
Verwijderd schreef op 13 januari 2003 @ 01:09:
[...]


>> rvtk:

Dat zou in principe weinig mogen uitmaken; verschil a=b of b=a heeft weinig belang, omdat -dachtik- MySQL LEFT JOIN condities als WHERE condities beschouwt. En jah ik weet dat distinct niet de mooiste oplossing is, maar het is hier ook 1 uur 8)

Anyway bokkel zijn oplossing zou toch correcte resultaten moeten opleveren.
>> Bonkie
Nu je het zo zegt komt me inderdaad wel weer als bekende oplossing voor :) (er valt natuurlijk weinig te joinen als niet de correcte tabellen worden geselecteerd). Als ik queries maak en ze willen niet dan denk ik nooit zo na, maar dan bouw ik ze een beetje om enzo en dan werkt het op gegeven moment wel. :7

Ik denk dat de topic-opener uit je antwoord wel een werkende query kan destilleren.

[ Voor 7% gewijzigd door rvtk op 13-01-2003 01:17 ]


Acties:
  • 0 Henk 'm!

  • Joror
  • Registratie: Augustus 2001
  • Laatst online: 11-03-2017

Joror

the eternal lurker

Verwijderd schreef op 12 januari 2003 @ 23:31:

Ik krijg nu rijen terug die er bijvoorbeeld als volgt uitzien:

code:
1
2
3
4
5
ID   Naam   Prijs
..............
23  FIETS  345.00 Euro 
23  FIETS  120.00 Euro
..............


Zit er structureel iets mis in de query? Ik kan de bug er niet uitkrijgen. Wil iemand mij hierbij helpen?
Mag ik uit het resultaat van de query opmaken dat een artikel meerdere prijzen kan hebben? Zoja, dan is het heel logisch dat hij een artikel twee maal teruggeeft.

Als een artikel enkel een prijs mag hebben, moet je even in je 'Price' tabel kijken hoevaak het produktID 23 voorkomt. Is dat meer dan een dan heb je dus meerdere prijzen per artikel.

Als dit voorkomt zal je je moeten afvragen waar die dubbele rijen vandaan komen. Ook kan je het veld 'produktID' in de tabel 'Price' unique maken, zodat mysql zelf met een error melding komt als je een dubbele prijs invoert.

(En de tabel 'Price' ook nog in de directe FROM zetten zoals bokkel zegt is onnodig, de LEFT JOIN is ook deel van de FROM deel van de query)

nada aka zilch, formerly known as zip


Acties:
  • 0 Henk 'm!

  • thomaske
  • Registratie: Juni 2000
  • Laatst online: 17-09 07:55

thomaske

» » » » » »

inderdaad, er gaat helemaal niets fout in deze join. Omdat er 2 rijen voorkomen in de Prijstabel (van hetzelfde produkt), ontstaan er (natuurlijk) 2 rijen!

Ik kan me voorstellen dat je de prijs in een aparte tabel hebt staan ivm het bijhouden van een eventuele prijs-historie.

Brusselmans: "Continuïteit bestaat niet, tenzij in zinloze vorm. Iets wat continu is, is obsessief, dus ziekelijk, dus oninteressant, dus zinloos."


Acties:
  • 0 Henk 'm!

  • sverzijl
  • Registratie: Januari 2001
  • Laatst online: 17-09 14:51
rvtk schreef op 13 January 2003 @ 00:51:
[...]


Je oplossing werkt inderdaad, maar een goede join is naar mijn idee een nettere oplossing.
een DISTINCT zal je probleem niet oplossen. Als je 'goed' kijkt zie je dat de 2 resulterende rows verschillend zijn (prijs verschilt). Een distinct filtert alleen volledig dubbele rijen eruit en dat is hier niet het geval.

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 12:52
sverzijl schreef op 13 January 2003 @ 09:39:
[...]

een DISTINCT zal je probleem niet oplossen. Als je 'goed' kijkt zie je dat de 2 resulterende rows verschillend zijn (prijs verschilt). Een distinct filtert alleen volledig dubbele rijen eruit en dat is hier niet het geval.


Idd, als je de dubbele artikelen eruit wilt halen, zul je dat moeten doen dmv een group by en een max() op de 'prijsdatum-kolom' (als je die informatie bijhoudt) zodat je de recentste prijs kunt ophalen.
Anders haal je gewoon de hoogste of de laagste of de gemiddelde prijs ofzo op....

[ Voor 11% gewijzigd door whoami op 13-01-2003 09:41 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Allereerst de oplossing van Bokkel:

code:
1
2
3
SELECT * from Artikels, Price
LEFT JOIN Price ON Artikels.productID = Price.productID
WHERE Artikels.catID='5000'


Geeft de volgende error:

Not unique table/alias: 'Price'

Ik ga nu andere suggestie proberen uit dit topic.

Acties:
  • 0 Henk 'm!

  • thomaske
  • Registratie: Juni 2000
  • Laatst online: 17-09 07:55

thomaske

» » » » » »

Verwijderd schreef op 13 januari 2003 @ 20:08:
[..]
Ik ga nu andere suggestie proberen uit dit topic.
Begrijp je waarom je dubbele rijen krijgt? Zolang je dat niet begrijpt heeft het weinig zin om een oplossing te proberen.

Je krijgt nu dubbele rijen met alleen een verschil in prijs, maar als je één rij wilt, welke van die 2 prijzen wil je dan hebben?

Brusselmans: "Continuïteit bestaat niet, tenzij in zinloze vorm. Iets wat continu is, is obsessief, dus ziekelijk, dus oninteressant, dus zinloos."


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 17-09 21:27

Creepy

Tactical Espionage Splatterer

Verwijderd schreef op 13 January 2003 @ 01:09:
[...]


>> rvtk:

Dat zou in principe weinig mogen uitmaken; verschil a=b of b=a heeft weinig belang, omdat -dachtik- MySQL LEFT JOIN condities als WHERE condities beschouwt. En jah ik weet dat distinct niet de mooiste oplossing is, maar het is hier ook 1 uur 8)

Anyway bokkel zijn oplossing zou toch correcte resultaten moeten opleveren.
Eehh.. ELKE join is te schrijven als een where condities (of meerdere) ZONDER het gebruik van het keyword join.
code:
1
2
3
select *
from tabel1, tabel2
where tabel1.blaat = tabel2.blaat

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb het probleem gevonden en zal het uitleggen a.h.v. een klein voorbeeld.

Het type van de colom productID is int(11).

In een csv file staan 2 producten met een productID:
0234
234

Dit zijn 2 verschillende producten, Bij het toevoegen in de database gaat die 1e nul verloren waardoor er 2 producten hetzelfde ID heeft.
Dus 2x een product met verschillende prijzen :) :)

Het omzetten van het productID naar het type varchar() moet dit oplossen.
Helaas lijkt het of de db-corrupt is geraakt bij het omzetten van int naar varchar. Maar daarvoor moet ik naar de provider.

iig bedankt voor de input, ik heb er veel aangehad.

Acties:
  • 0 Henk 'm!

  • thomaske
  • Registratie: Juni 2000
  • Laatst online: 17-09 07:55

thomaske

» » » » » »

het is niet slim dat een primary key meer betekenis heeft dan het identificeren van een database-record. Wat ik dus in jouw geval zou doen:
code:
1
2
3
4
5
tbl_product
-----------
prd_id      int(11)     auto_increment, PK
prd_nummer  varchar(25) unique
prd_naam    varchar(125)


prd_id staat enkel en alleen voor de identificatie van je record!

[tevens]
tevens is het ook sneller wanneer je een numeriek veld als primary key hebt. Deze zijn namelijk beter te indexeren, en die indexen heb je hard nodig met het joinen van je producten tabel aan andere tabellen

[ Voor 25% gewijzigd door thomaske op 13-01-2003 22:15 ]

Brusselmans: "Continuïteit bestaat niet, tenzij in zinloze vorm. Iets wat continu is, is obsessief, dus ziekelijk, dus oninteressant, dus zinloos."


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Zoiets heb ik ook, maar voor het voorbeeld heb ik het uitgekleed:

code:
1
2
3
4
5
6
7
8
CREATE TABLE shop_Artikels (
  artID int(11) NOT NULL auto_increment,
  productID varchar(100) NOT NULL default '0',
  catID varchar(10) NOT NULL default '0',
  merkName varchar(150) NOT NULL default '',
  description text NOT NULL,
  PRIMARY KEY  (artID),
) TYPE=MyISAM;


Gaat dat zo goed dan?

[ Voor 12% gewijzigd door Verwijderd op 13-01-2003 22:31 ]


Acties:
  • 0 Henk 'm!

  • thomaske
  • Registratie: Juni 2000
  • Laatst online: 17-09 07:55

thomaske

» » » » » »

Verwijderd schreef op 13 januari 2003 @ 22:30:
code:
1
productID varchar(100) NOT NULL default '0',
MySQL is dan wel niet zo strict met default waardes, maar ik zou geen default waarde instellen
code:
1
catID varchar(10) NOT NULL default '0',
ik neem aan dat het een Foreign Key is naar een categories tabel? Dan zou ik geen varchar gebruiken maar een int

En verder na je PRIMARY KEY nog even zorgen dat je productID uniek is:
code:
1
2
3
4
5
6
7
8
9
CREATE TABLE shop_Artikels (
  artID int(11) NOT NULL auto_increment,
  productID varchar(100) NOT NULL,
  catID int(11) NOT NULL,
  merkName varchar(150) NOT NULL default '',
  description text NOT NULL,
  PRIMARY KEY  (artID),
  UNIQUE (productID)
) TYPE=MyISAM;

Brusselmans: "Continuïteit bestaat niet, tenzij in zinloze vorm. Iets wat continu is, is obsessief, dus ziekelijk, dus oninteressant, dus zinloos."


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 16-09 09:15

Janoz

Moderator Devschuur®

!litemod

IS het niet een id om voor de product nummers gewoon een 1 te zetten? Hierdoor krijg je 1234 en 10234. Voorloopnullen worden niet verwijderd, originele productnummers zijn simpel te achterhalen en er hoeft niet inefficient met strings gewerkt te worden.

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


Acties:
  • 0 Henk 'm!

  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

Creepy schreef op 13 januari 2003 @ 20:22:
[...]

Eehh.. ELKE join is te schrijven als een where condities (of meerdere) ZONDER het gebruik van het keyword join.
code:
1
2
3
select *
from tabel1, tabel2
where tabel1.blaat = tabel2.blaat
Hoe wil jij een LEFT JOIN maken op deze manier? Wat je namelijk hier neer zet is een INNER JOIN...

Programmer - an organism that turns coffee into software.


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 12:52
LuCarD schreef op 14 januari 2003 @ 10:33:
[...]


Hoe wil jij een LEFT JOIN maken op deze manier? Wat je namelijk hier neer zet is een INNER JOIN...


Dat hangt meestal af van het DBMS. In Oracle doe je dat dmv het (+) - teken, in Informix dmv het OUTER keyword, etc....

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • sverzijl
  • Registratie: Januari 2001
  • Laatst online: 17-09 14:51
LuCarD schreef op 14 January 2003 @ 10:33:
[...]


Hoe wil jij een LEFT JOIN maken op deze manier? Wat je namelijk hier neer zet is een INNER JOIN...
inderdaad.
Het kan overigens wel, maar dan zul je er een UNION aan moeten toevoegen met subselect (voor zover MySQL dat ondersteunt). Maakt het er echter niet echt leesbaarder op. Was vroeger met DB2 helaas de enige manier.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Janoz schreef op 14 januari 2003 @ 10:13:
IS het niet een id om voor de product nummers gewoon een 1 te zetten? Hierdoor krijg je 1234 en 10234. Voorloopnullen worden niet verwijderd, originele productnummers zijn simpel te achterhalen en er hoeft niet inefficient met strings gewerkt te worden.
Dit is idd een goed idee. Maar scheelt het echt veel in tijd bij het werken met string ipv ints.

Acties:
  • 0 Henk 'm!

  • sverzijl
  • Registratie: Januari 2001
  • Laatst online: 17-09 14:51
hang er vanaf of hoe ints worden opgeslagen/verwerkt in mySQL. De meeste RBMS-en slaan integers gewoon op als een string van characters ('12' kost dan dus 2 bytes, '12345' kost 5 bytes). In dat geval is de (B-tree) indexering net zo snel als een (fixed width!) character field.

Acties:
  • 0 Henk 'm!

  • thomaske
  • Registratie: Juni 2000
  • Laatst online: 17-09 07:55

thomaske

» » » » » »

sverzijl schreef op 14 January 2003 @ 13:07:
hang er vanaf of hoe ints worden opgeslagen/verwerkt in mySQL. De meeste RBMS-en slaan integers gewoon op als een string van characters ('12' kost dan dus 2 bytes, '12345' kost 5 bytes). In dat geval is de (B-tree) indexering net zo snel als een (fixed width!) character field.
Dit kan ik me totaal niet voorstellen, dat het zo in de meeste RDBMS-en geregeld is. Is namelijk erg inefficient

Brusselmans: "Continuïteit bestaat niet, tenzij in zinloze vorm. Iets wat continu is, is obsessief, dus ziekelijk, dus oninteressant, dus zinloos."

Pagina: 1