[mysql] Laatste 3 nieuwe produkten per rubriek weergeven

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Ik heb hier al eens eerder een topic overgemaakt, maar ben er helaas nog steeds niet uit. In een overzicht wil ik alle rubrieken weergeven en dan bij elke rubriek de laatste 3 produkten in die rubriek.

Ik heb een rubrieken en een produkten tabel:

rubrieken
- id
- naam

produkten
- id
- rubriekid
- naam

Nu had ik zelf als query:
MySQL:
1
2
3
4
5
6
7
8
9
10
11
SELECT
 r.id AS rubriekid,
 r.naam AS rubrieknaam,
 p.id AS produktid,
 p.naam AS produktnaam
FROM
 rubrieken r
LEFT JOIN
 (SELECT id,naam,rubriekid FROM produkten ORDER BY id DESC LIMIT 3) AS p
ON
 (p.rubriekid=r.id)

Deze query laat nu maar 3 produkten zien, ook al zijn er meerdere. Dit komt natuurlijk door de subquery die gelimiteerd is tot 3. Nu kan ik natuurlijk over alle rubrieken loopen, maar als ik 20 rubrieken heb, zijn dat al gauw 21 queries. Dit wil ik liever niet. Ik zou het graag bij 1 query houden.

Acties:
  • 0 Henk 'm!

  • marco_balk
  • Registratie: April 2001
  • Laatst online: 20-06 21:52
En als je het nu eens van de andere kant beredeneert?
"Ik wil van de producten de rubrieken weten".

Met een loopje kun je dan door je producten heenlopen en dan kijk je bij iedere loop of de rubriek overeenkomt met de rubriek van het product uit de vorige loop. Is dat niet het geval, dan krijg je dus producten uit een andere rubriek en moet je weer je "rubriek-dingen" tonen.

Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Het gaat niet zo zeer om het tonen, maar om de mysql resultset die ik terugkrijg.
Het volgende kan ik makkelijk terugkrijgen:

Witgoed Wasmachine
Witgoed Droger
Witgoed Koelkast
Witgoed Vriezer
Audio Versterker
Audio Radio
Audio Casette
Audio CD-speler
Audio DVD-speler

Alleen nu moet hij dit beperken tot 3 stuks, dus:

Witgoed Wasmachine
Witgoed Droger
Witgoed Koelkast
Audio Versterker
Audio Radio
Audio Casette

Nu gaat het in mijn geval om produkten dan en die tabel kan vrij groot zijn. In het voorneeld gebruik ik subrubrieken.

Acties:
  • 0 Henk 'm!

  • J2pc
  • Registratie: Oktober 2002
  • Niet online

J2pc

UT Tux Edition

RSD schreef op maandag 20 april 2009 @ 09:55:
Ik heb hier al eens eerder een topic overgemaakt, maar ben er helaas nog steeds niet uit. In een overzicht wil ik alle rubrieken weergeven en dan bij elke rubriek de laatste 3 produkten in die rubriek.

Ik heb een rubrieken en een produkten tabel:

rubrieken
- id
- naam

produkten
- id
- rubriekid
- naam

Nu had ik zelf als query:
MySQL:
1
2
3
4
5
6
7
8
9
10
11
SELECT
 r.id AS rubriekid,
 r.naam AS rubrieknaam,
 p.id AS produktid,
 p.naam AS produktnaam
FROM
 rubrieken r
LEFT JOIN
 (SELECT id,naam,rubriekid FROM produkten ORDER BY id DESC LIMIT 3) AS p
ON
 (p.rubriekid=r.id)

Deze query laat nu maar 3 produkten zien, ook al zijn er meerdere. Dit komt natuurlijk door de subquery die gelimiteerd is tot 3. Nu kan ik natuurlijk over alle rubrieken loopen, maar als ik 20 rubrieken heb, zijn dat al gauw 21 queries. Dit wil ik liever niet. Ik zou het graag bij 1 query houden.
Volgens mij gaat die query sowieso niet werken, aangezien je volgens mij de 3 laatse records ophaalt, en dan kijkt bij welke categorie die horen.

SQL:
1
2
3
SELECT r1.velden, p1.velden
FROM rubriek r1 JOIN product p1 ON r1.rubriekId = p1.rubriekId
WHERE p1.productId IN (SELECT TOP 3 p2.productId FROM Product p2 WHERE p2.rubriek = r1.rubriekId ORDER BY p2.productId DESC)


Deze kijkt per rubriek welke 3 producten erbij horen. Het is een beetje pseudo (lui) en mssql ipv mysql (ervaring). Maar volgens mij moet zoiets wel werken.

offtopic:
eigenlijk wil je de laatste 3 producten op toevoegings-datum doen natuurlijk ;)

"The computer is incredibly fast, accurate, and stupid. Man is unbelievably slow, inaccurate, and brilliant. The marriage of the two is a challenge and opportunity beyond imagination." © Stuart G. Walesh


Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Alleen dat top 3 werkt in myssql niet volgens mij. Ik kan nu wel limit 3 doen, maar dan heb ik hetzelfde als voorheen.

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
RSD schreef op maandag 20 april 2009 @ 13:43:
Alleen dat top 3 werkt in myssql niet volgens mij. Ik kan nu wel limit 3 doen, maar dan heb ik hetzelfde als voorheen.
Dan moet je misschien een limit op de sub-query doen ;)

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • J2pc
  • Registratie: Oktober 2002
  • Niet online

J2pc

UT Tux Edition

RSD schreef op maandag 20 april 2009 @ 13:43:
Alleen dat top 3 werkt in myssql niet volgens mij. Ik kan nu wel limit 3 doen, maar dan heb ik hetzelfde als voorheen.
Nee hoor, de subquery zit op een andere plek. Probeer gewoon eens de mysql versie van TOP (zou zomaar limit kunnen zijn, dunno). Als je maar de 3 bovenste rijen pakt in de subquery :)

eigenlijk wat Woy dus ook zegt

[ Voor 26% gewijzigd door J2pc op 20-04-2009 13:49 ]

"The computer is incredibly fast, accurate, and stupid. Man is unbelievably slow, inaccurate, and brilliant. The marriage of the two is a challenge and opportunity beyond imagination." © Stuart G. Walesh


Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
#1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
RSD schreef op maandag 20 april 2009 @ 13:50:
#1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
Dan weet je dus wat je te doen staat :?

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • J2pc
  • Registratie: Oktober 2002
  • Niet online

J2pc

UT Tux Edition

in de doc van v6 staan die functies gewoon. Tijd voor een update.

Vraagje, als LIMIT niet ondersteund werd, hoe weet je dan dat jouw query werkte? (per rubriek weliswaar)

"The computer is incredibly fast, accurate, and stupid. Man is unbelievably slow, inaccurate, and brilliant. The marriage of the two is a challenge and opportunity beyond imagination." © Stuart G. Walesh


Acties:
  • 0 Henk 'm!

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Niet direct een oplossing, maar waar je naar op zoek bent heet een GROUPWISE MAXIMUM, misschien kun je hier eens op googlen (Hoewel op zich de juiste antwoorden hieroboven al gegeven zijn, wellicht nog interessant om iets van te leren :) )

Deze link bijvoorbeeld: http://dev.mysql.com/doc/...mum-column-group-row.html

Oops! Google Chrome could not find www.rijks%20museum.nl


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

J2pc schreef op maandag 20 april 2009 @ 13:58:
in de doc van v6 staan die functies gewoon. Tijd voor een update.
Naar een Alpha versie... tuurlijk. Afgezien daarvan wordt de foutmelding ook in de 6.0-manual nog beschreven, dus ik vraag me af hoe jij er precies bij komt dat dit wel in 6.0 gaat werken. 't Gaat hier namelijk om de limit in de subquery, niet het feit dat je een IN gebruikt.

Ik kan zo gauw zelf geen variant bedenken waarbij de query in een keer kan, per subcategorie, zonder een dergelijke limit te gebruiken. Tenzij je een variant kan bedenken waarbij de producten per categorie een rownumber krijgen ofzo en je uiteindelijk via subqueries op dat rownumber kunt filteren.
Maar uiteindelijk ben je dan waarschijnlijk beter af met de boel in losse queries te doen. En mocht dat performance-technisch onwenselijk zijn, kan je altijd nog een caching-laag toevoegen...

Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Ik had het idd al geprobeerd met een soort counter. Dit werkt wel goed, alleen het sorteren gaat dan weer fout, omdat hij altijd bij de oudste begint te tellen en vervolgens na 3 tellen naar de volgende categorie gaat. Zo heb je dus altijd de oudste 3 ipv de nieuwste 3.

Ik denk dat ik maar een aparte tabel ga maken met de ids erin en die update als er wat verandert.

Acties:
  • 0 Henk 'm!

  • J2pc
  • Registratie: Oktober 2002
  • Niet online

J2pc

UT Tux Edition

ACM schreef op maandag 20 april 2009 @ 14:17:
[...]

Naar een Alpha versie... tuurlijk. Afgezien daarvan wordt de foutmelding ook in de 6.0-manual nog beschreven, dus ik vraag me af hoe jij er precies bij komt dat dit wel in 6.0 gaat werken. 't Gaat hier namelijk om de limit in de subquery, niet het feit dat je een IN gebruikt.

Ik kan zo gauw zelf geen variant bedenken waarbij de query in een keer kan, per subcategorie, zonder een dergelijke limit te gebruiken. Tenzij je een variant kan bedenken waarbij de producten per categorie een rownumber krijgen ofzo en je uiteindelijk via subqueries op dat rownumber kunt filteren.
Maar uiteindelijk ben je dan waarschijnlijk beter af met de boel in losse queries te doen. En mocht dat performance-technisch onwenselijk zijn, kan je altijd nog een caching-laag toevoegen...
Ik had geloof ik al aangegeven dat ik mssql ervaring heb, geen mysql ervaring. Ik had even gegoogled naar mysql docs, en de hoogste versie gepakt waar deze versies in staan. Zo kwam ik daarbij.
Als dat een alpha is, heb ik dat niet gezien. Excusez moi.

ontopic
Als je toch gaat loopen, haal dan 1 keer een lijst met categorien op, en haal dan per categorie de laatste 3 producten op. Dan hoef je ook geen subquerys te gebruiken.

zoiets
SQL:
1
2
SELECT rubriek.rubriekID, rubriek.Name
FROM rubriek


en dan per rubriekID
SQL:
1
2
3
4
SELECT TOP 3 product.naam, product.productID
FROM product
WHERE product.rubriekID = ?
ORDER BY product.productID DESC

vervang TOP 3 voor de mysql variant, ? voor een rubriekID die je eerder hebt opgehaald.

[ Voor 17% gewijzigd door J2pc op 20-04-2009 15:51 ]

"The computer is incredibly fast, accurate, and stupid. Man is unbelievably slow, inaccurate, and brilliant. The marriage of the two is a challenge and opportunity beyond imagination." © Stuart G. Walesh

Pagina: 1