Hallo allemaal,

Allereerste wil ik graag iedereen van harte bedanken. Ik vind het nu echt een beetje ingewikkeld te worden en zit dagen te zoeken en dingen uitproberen maar steeds niet wat ik wil.

Hier is dus mijn dynamische Query, zo gaat ie er uit zien wanneer hij Gets van attributen krijg.

SELECT * FROM Articles AS a,
Users AS g,
Province AS p,
Attrib_couple AS at
WHERE at.pre_id in (1,2,3)
AND at.id = a.id
AND a.user_id = g.user_id
AND p.pro_id = a.pro_id
AND a.catid = 6
AND p.pro_id = 3
AND (a.artitle LIKE "%something%" or a.artext LIKE "%something%")
GROUP BY a.id ORDER BY a.ranking DESC LIMIT 0,12


ik heb 3 producten.
Product1 eigenschappen = nieuw,zwart en staal
Product2 eigenschappen = nieuw,grijs en plastic
Product3 eigenschappen = oud,zwart en plastic
Stel Eigenschappen zijn:
nieuw = 1
zwart = 2
staal = 3
En mijn Attrib_couple Table zit als volgt uit

ID| article_id| pre_id
12| 100 | 1
13| 100 | 2
14| 100 | 3
15 | 200 | 1
16 | 200 | 2
17 | 200 | 8
18 | 400 | 1



Wanner ik pre_id 1 binnen krijg dan moet ik alle 3 artikels zien en wanneer ik pre_id 1 en 2 binnen krijg moet ik artikel met id (100 en 200) zien en als laatste als ik pre_id 1,2 en 3 binnen krijg moet ik alleen artikel met id (100) zien..

Ik wou graag dit in een Query doen helaas het is me niet gelukt ik heb ook having count(*) <,> =... left join...van alles wat geprobeerd.

Graag zie ik jullie reactie en Ik hoop dat ik jullie niet veel hoofdpijn ga bezorgen.

Alvast bedankt,
Met vriendelijk groeten,
Ari
Ger van Steenderen op 17/03/2012 10:21:44

Ik denk niet dat jou gedachte goed is, wat jij doet is namelijk hetzelfde als dit:

SELECTarticle_id
FROM article
JOIN attributes USING article_id
WHERE attributes.pre_id IN (1,2,3)


Dat is absoluut niet waar. Ga het maar eens testen. De voorwaarde die je in de ON clause zet zijn niet hetzelfde als de voorwaarde die je in een WHERE clause zet. In een ON clause is het alleen gericht op de join tabel, maar niet op de total uitkomst. Daarom is de join die ik maakte ook niet uitvoerbaar in een impliciete join. Daar zou je het namelijk wel in de WHERE moeten stoppen en dan geldt het opeens voor alle rijen in de uitkomst waardoor het zou zijn zoals jij zegt.

Anyway, ik heb mijn oplossing net getest en het werkt (hoewel ik wel zag dat ik wat tikfoutjes in de query had en dat je de alias al in de join voorwaarden moet gebruiken).

SELECT article.article_id
FROM article
INNER JOIN attributes a1 ON (
  article.article_id = a1.article_id
  AND a1.pre_id = 1
)
INNER JOIN attributes a2 ON (
  article.article_id = a2.article_id
  AND a2.pre_id = 2
)
INNER JOIN attributes a3 ON (
  article.article_id = a3.article_id
  AND a3.pre_id = 3
) 

Jouw query heb ik echter niet aan de praat kunnen krijgen en omdat ik eerlijk moet zeggen dat ik hem ook niet helemaal begrijp.... zou ik graag een uitleg zien :-)
Je hebt gelijk, jou query werkt ook, ik heb niet goed gekeken. Overigens kan ie wel impliciet (SELECT a.article_id FROM articles a, attributes a1, attributes a2 enz).


SELECT article.article_id, aka.list
FROM article
INNER JOIN (
	SELECT article_id, GROUP_CONCAT(pre_id ORDER BY pre_id) AS list 
	FROM attributes 
	WHERE pre_id IN (1,2,3)
	GROUP BY article_id
	HAVING (count(article_id) = 3)) AS aka

Zou in jou voorbeeld opleveren:
100 1,2,3
Is dit misschien duidelijker, wat begrijp je anders niet?
Met een impliciete zou het dan gaan door a1.pre_id = 1 AND a2.pre_id = 2 etc. Hmm, zou ook kunnen inderdaad.
Jouw query zal ik later nog eens proberen, nu helaas geen tijd meer. Zoals ik al zie vind ik de mijne namelijk niet echt elegant.
@Erwin H en @Ger van Steenderen, Hartelijk dank voor jullie moeite en ik waardeert heel erg :)

beide werken goed :)

Ik vind de eerst oplossing van Ger van Steenderen wat simpeler en makkelijker en ik begrijpt een deel niet zoals GROUP_CONCAT en AS ak maar welke het beter of sneller is na dat mijn data miljoen records bevat...!!!!

ooit heb ik iets over mysql bits of bittz (ik ben het even kwijt) gehoord, dat bijv. alle 3 attrib_ids als bitz in database moet opslaan dus zo iets

Attributen_koppel
-ID (auto_increment)
-Pre_id ( Hier zit dan soort Hash code in bijv(xghjhg53554sdkshdh) en is zelfde als (1391, 1396, 1397) of meer dan 3 attributen.
-article_id

dus wanneer ik die query doe er is een functie de in die Hash gaat zoeken en als hij bijv. attrib_id 1391 krijgt dan laat hij 4 producten zien of attrib_id 1391, 1396, 1397 dan wordt een product.

Ik heb lang op Google gezocht maar helaas kon niks van vinden dus ik vraag graag jullie advies.

Ik hoop dat jullie mij verhaal kunnen begrijpen :)




[size=xsmall]Toevoeging op 18/03/2012 00:10:30:[/size]

@Ger van Steenderen helaas het is mij niet gelukt om die query uitbreiden :(

SELECT *
FROM article AS a, user AS g, province AS p
WHERE
a.catid = 6
AND p.pro_id = 3
AND (a.artitel LIKE "%a%" or a.artext LIKE "%a%")

JOIN
(SELECT article_id,
GROUP_CONCAT(pre_id ORDER BY pre_id) AS list
FROM
attrib_koppel
WHERE
pre_id IN (1391, 1396, 1397)
GROUP BY
article_id
HAVING (list = '1391,1396,1397')) AS ak USING (article_id) ORDER BY a.ranking DESC

Ik hoor het graag :)
GROUP_CONCAT plakt de waarden van één of meer kolom(men) aan elkaar gescheiden door een komma. AS zijn aliassen, in goede SQL wordt geen * gebruikt, maar de kolommen netjes uitgetypt en dan hoef je niet telkens die hele tabelnaam te typen.

Ik zou niet weten waarom je het pre_id op een andere manier moet opslaan, en ik zou het ook niet doen.

Jouw query kan natuurlijk nooit gaan werken want je gooit implicitiete en explicitie joins door elkaar, dat kan niet.

SELECT a.*, u.user_name, p.Province
FROM articles AS a
JOIN    
    (SELECT ID
     FROM
     attrib_koppel
    WHERE
        pre_id IN (1391, 1396, 1397)
    GROUP BY
        ID
    HAVING (COUNT(ID) = 3)) AS ak USING (ID)
JOIN user_id AS u ON u.user_id = a.user_id
JOIN province AS p ON p.pro_id = u.pro_id
WHERE
	a.catid = 6
	AND
		(a.artitel LIKE "%a%"
		OR
		a.artext LIKE "%a%")

De eerste join is op een derived table (inline view) dmv van een subquery, daarna wordt de user_id tabel gelinkt via de user id en tot slot de provincie tabel aan de usertabel.
Daarna ga je filteren.
aha oke ik snap hem, wat mij nu op viel is dat je niet meer

HAVING (list = '1391,1396,1397')) AS ak USING (ID)

maar

HAVING (COUNT(ID) = 3)) AS ak USING (ID)

maak het uit qua werking of snelheid of iets anders ?? want ik vind de met list fijner werken bij mijn script :)
Ja dat kan in snelheid best wel eens wat uitmaken, zeker op grote tabellen.
Daarnaast geeft dit je wat meer flexibiliteit, bv als je wilt dat 2 van de 3 pre_id's hoeven te matchen en het niet uitmaakt welke.

[size=xsmall]Toevoeging op 18/03/2012 17:14:48:[/size]

Lol, als ik gereageerd heb krijg dit:
Reageren op Join om artikelen ophalen met attributen, gaat maar niet lukken :(
Oke dus wel HAVING (COUNT(ID) = 3)) AS ak USING (ID) gebruiken ?

[size=xsmall]Toevoeging op 19/03/2012 00:29:02:[/size]

of HAVING (list = '1391,1396,1397')) AS ak USING (ID) ?
Goed morgen,

en bedankt :-)

Reageren