[MySQL] Group by + Order by werkt niet

Pagina: 1
Acties:

  • plakbandrol
  • Registratie: Juni 2002
  • Laatst online: 12-02 12:36
Ik ben een script aan het maken die voor een tvgids de komende tv progs laat zien, dus voor elke zender moet hij het eerstvolgende programma tonen. Dit wordt vervolgens in een rss feed gestopt (maar das offtopic)

Dit is m'n query op dit moment (beetje ingekort)
SELECT * FROM tvgids_progdb p LEFT JOIN tvgids_zenders z
ON p.zender = z.id
WHERE p.tijd_start > now()
group by p.zender
order by p.tijd_start
Het idee is dus simpel; geef alle tv programma's die nog moeten beginnen, sorteer deze op begintijd, en groepeer ze vervolgens op zender, het resultaat zou iets in deze richting moeten zijn:

ned1 - 14:00 - journaal
ned2 - 14:15 - studio sport
etc

Maar het probleem lijkt te zijn dat wanneer ik group by gebruik, hij de order by negeert, ik krijg allemaal programma's die pas vanavond laat beginnen e.d

Als ik group by weglaat kloppen de tijden wel maar krijg ik van 1 zender meerdere resultaten terwijl ik het dus per zender moet weten

Ik heb ook al geprobeerd distinct te gebruiken op zender, maar dit lijkt volkomen genegeerd te worden...

Wie heeft er suggesties?

-edit-

hier ff screenie voor de duidelijkheid

tvgids_progdb:
Afbeeldingslocatie: http://4aal.nl/temp/tvgids_progdb.jpg

tvgids_zenders:
Afbeeldingslocatie: http://4aal.nl/temp/tvgids_zenders.jpg

[ Voor 17% gewijzigd door plakbandrol op 19-05-2004 13:30 ]


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 24-05 14:53

NMe

Quia Ego Sic Dico.

Je kan ook meerdere velden bij de group by invullen, misschien dat dat wat uithaalt? ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • plakbandrol
  • Registratie: Juni 2002
  • Laatst online: 12-02 12:36
NMe84 schreef op 19 mei 2004 @ 13:20:
Je kan ook meerdere velden bij de group by invullen, misschien dat dat wat uithaalt? ;)
ook al geprobeerd maar wil niet lukken

het gewenste resultaat zou eigenlijk moeten zijn, dat elke 'groep' die hij aanmaakt door group by, afzonderlijk geordend moet worden, dat lijkt ie niet te doen

[ Voor 27% gewijzigd door plakbandrol op 19-05-2004 13:22 ]


  • Brothar
  • Registratie: Oktober 2000
  • Laatst online: 04-02 09:14

Brothar

meester

order by p.tijd_start, p.zender

dan krijg je tijdsvolgordelijk de programma's, en wanneer meerdere programma's op dezelfde tijd beginnen, voor die tijd een overzicht op zendervolgorde.

Ik denk dat er helemaal niets genegeerd wordt, maar dat je dataset dusdanig is dat het líjkt of een commando wordt genegeerd.

Je moet minimaal 2 programma's per zender hebben, en eveneens minimaal 2 programma's (uiteraard van verschillende zenders) die op een zelfde tijdstip beginnen.

[ Voor 46% gewijzigd door Brothar op 19-05-2004 13:24 ]

eagle


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 24-05 14:53

NMe

Quia Ego Sic Dico.

Heb je per se een left join nodig? Kan het niet met inner join, distinct en zonder group by?

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 00:01

Janoz

Moderator Devschuur®

!litemod

Order by slaat op de gehele result set. Dat je een group by op zender wilt gebruiken is de juiste gedachte. De orderby werkt echter anders. Sowieso is het maar raar van MySQL dat hij dit uberhaupt pikt.

Waarjij meer op zoek naar bent is MIN(tijd.start) icm een HAVING clause.

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


  • n00bs
  • Registratie: Augustus 2002
  • Laatst online: 13:10

n00bs

Het is weer Zomer!

wat is sowieso niet netjes vind is: ON p.zender = z.id
doe dan p.id = z.id

in ieder geval zou het makkelijk zijn als je even de tabellen hier post

  • plakbandrol
  • Registratie: Juni 2002
  • Laatst online: 12-02 12:36
NMe84 schreef op 19 mei 2004 @ 13:22:
Heb je per se een left join nodig? Kan het niet met inner join, distinct en zonder group by?
kan ook wel op andere manieren, maar die left join is niet echt het probleem hier, das alleen om de naam van de tv zender bij het programma te stoppen, en dat werkt verder ook goed

  • plakbandrol
  • Registratie: Juni 2002
  • Laatst online: 12-02 12:36
n00bs schreef op 19 mei 2004 @ 13:23:
wat is sowieso niet netjes vind is: ON p.zender = z.id
doe dan p.id = z.id
dat zou niets opleveren, beide hebben een eigen index en die 2 ID's hebben geen relatie tot elkaar

p.zender is het ID van de zender, maar zoals gezegd is dit het probleem hier niet echt
in ieder geval zou het makkelijk zijn als je even de tabellen hier post
ik zal wel even een screenie maken

  • Brothar
  • Registratie: Oktober 2000
  • Laatst online: 04-02 09:14

Brothar

meester

Neem dan ook's de testset:

Ned1 8.00 uur journaal
Ned2 8.00 uur journaal voor SH
Ned1 8.30 uur journaal
Ned3 8.30 uur schoolTV
Ned2 9.00 uur De rijdende Rechter

Bovenstaand overzicht krijg je dan met order tijd, zender
terwijl je met order zender, tijd het lijstje
Ned1 8.00 uur journaal
Ned1 8.30 uur journaal
Ned2 8.00 uur journaal voor SH
Ned2 9.00 uur De rijdende Rechter
Ned3 8.30 uur schoolTV
krijgt

[ Voor 45% gewijzigd door Brothar op 19-05-2004 13:33 ]

eagle


  • n00bs
  • Registratie: Augustus 2002
  • Laatst online: 13:10

n00bs

Het is weer Zomer!

zal wel aan mij liggen maar wat is volgens jou de relatie tussen p.zender en z.id :? de 1 mag zelfs null waarden hebben en is van een ander type. En wat is het doel van die andere tabel? ik volg het niet echt... zal wel aan mij liggen maar ik vind het niet echt logisch allemaal

[ Voor 5% gewijzigd door n00bs op 19-05-2004 13:38 ]


  • plakbandrol
  • Registratie: Juni 2002
  • Laatst online: 12-02 12:36
n00bs schreef op 19 mei 2004 @ 13:35:
zal wel aan mij liggen maar wat is volgens jou de relatie tussen p.zender en z.id :?
p.zender is de zender uitgedrukt in een getal, z.id is de ID van de tabel zenders, die zorgt ervoor dat de zendernaam voluit in de resultaten komt

maar nogmaals, dat is niet echt het probleem hier
de 1 mag zelfs null waarden hebben. En wat is het doel van die andere tabel? ik volg het niet echt... zal wel aan mij liggen maar ik vind het niet echt logisch allemaal
welke andere tabel?

de een staan alle programma's in, de ander is alleen een databasje met de namen van de zenders

  • Brothar
  • Registratie: Oktober 2000
  • Laatst online: 04-02 09:14

Brothar

meester

Ik zou een andere database maken:
- tabel zenders
- tabel programma's
- (koppel)tabel programmagids. Hierin zitten dan verwijzende sleutels naar de eerste 2 tabellen. en de tijden.

[ Voor 23% gewijzigd door Brothar op 19-05-2004 13:42 ]

eagle


  • plakbandrol
  • Registratie: Juni 2002
  • Laatst online: 12-02 12:36
Het resultaat van wat ik nu heb:

group by p.zender
order by p.tijd_start

is dit:
Cart. - 20:10 - Top cat
RTL4 - 12:00 - The bold and the beautiful
Ned2 - 20:45 - Voetbal: 100 jaar FIFA: Frankrijk - Brazilië
Geo. - 01:00 - The sea hunters
Nick. - 02:15 - Calimero
Ned3 - 07:28 - Paniek in het dorp
Ned1 - 07:30 - NOS-Journaal
Vero. - 10:35 - Beugelbekkie
RTL5 - 14:00 - RTL Z Nieuws
NET5 - 14:25 - Holiday TV
Yorin - 18:05 - Mad about you
SBS6 - 19:35 - Shownieuws
Disc. - 21:00 - Ray Mears' extreme survival: Sahara/Morocco
De zenders zijn dus mooi gegroepeerd maar de tijden kloppen voor geen meter

Als ik group by weghaal krijg je dit
Ned3 - 13:42 - Melatten
Nick. - 13:45 - Hey Arnold!
Ned1 - 13:45 - NCRV Natuurlijk - Waterlanders
Ned3 - 13:52 - Kijkers
Cart. - 13:55 - Ed, Edd 'n' Eddy
Ned3 - 13:55 - Poesjes
Geo. - 14:00 - Wild!Life adventures: Bear wars
Disc. - 14:00 - Thunder races: Reverse wheelie
Ned3 - 14:03 - Geheimen van het schoolplein
Vero. - 14:05 - Sitting ducks
Ned3 - 14:10 - Villa krakers
Ned1 - 14:10 - Man bijt hond
Vero. - 14:15 - Kids from room 402
(etc)
Dan kloppen de tijden wel, maar zijn de zenders niet gegroepeerd

[ Voor 5% gewijzigd door plakbandrol op 19-05-2004 13:43 ]


  • Brothar
  • Registratie: Oktober 2000
  • Laatst online: 04-02 09:14

Brothar

meester

haal nu 's je group weg en verander de order zoals ik boven heb aangegeven

eagle


  • plakbandrol
  • Registratie: Juni 2002
  • Laatst online: 12-02 12:36
Brothar schreef op 19 mei 2004 @ 13:41:
Ik zou een andere database maken:
- tabel zenders
- tabel programma's
- (koppel)tabel programmagids. Hierin zitten dan verwijzende sleutels naar de eerste 2 tabellen. en de tijden.
ik zie niet in waarom ik een extra tabel moet maken voor iets wat gewoon rechtstreeks gedaan kan worden..

in de programma database staat bijvoorbeeld

naam: Journaal
zender: 1

vervolgens wordt ie gemerged en krijg je

naam: Journaal
zender: 1
zender_kort: Ned1

maar nogmaals, die join van zendernamen werkt verder prima, dat is het probleem niet, het probleem is dat hij niet zenders wil groeperen en tegelijkertijd op tijd wil sorteren

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
SELECT * FROM tvgids_progdb p LEFT JOIN tvgids_zenders z
ON p.zender = z.id
WHERE p.tijd_start > now()
group by p.zender
order by p.tijd_start
belachelijk trouwens dat je hier geen foutmelding op krijgt :X maar het feit dat je maar 1 kolom uit de select list in je query hebt is wel de oorzaak van je probleem. MySQL neemt blijkbaar een willekeurige starttijd voor elke zender. Je moet aggregate functies in je select statement opnemen voor elke kolom die niet in je group by staat.

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


Verwijderd

toen ik de titel zag dacht ik "daar gaan we weer"; zoals ik al dacht.

zoals janoz al zei:
group by heeft te maken met summary functions

net te laat...

[ Voor 11% gewijzigd door Verwijderd op 19-05-2004 13:52 ]


  • plakbandrol
  • Registratie: Juni 2002
  • Laatst online: 12-02 12:36
Brothar schreef op 19 mei 2004 @ 13:46:
haal nu 's je group weg en verander de order zoals ik boven heb aangegeven
resultaat (maar even limit 25 erbij gezet anders werd de lijst nogal lang)
Ned3 - 13:52 - Kijkers
Ned3 - 13:55 - Poesjes
Cart. - 13:55 - Ed, Edd 'n' Eddy
Geo. - 14:00 - Wild!Life adventures: Bear wars
Disc. - 14:00 - Thunder races: Reverse wheelie
Ned3 - 14:03 - Geheimen van het schoolplein
Vero. - 14:05 - Sitting ducks
Ned1 - 14:10 - Man bijt hond
Ned3 - 14:10 - Villa krakers
RTL4 - 14:15 - RTL Shop
Yorin - 14:15 - Homeshopping
Vero. - 14:15 - Kids from room 402
NET5 - 14:15 - Holiday TV
Nick. - 14:20 - De wild Thornberrys
Cart. - 14:20 - Samurai Jack
SBS6 - 14:25 - Wannahaves
Ned3 - 14:28 - Tijd voor Tim
Ned1 - 14:35 - Lingo
Vero. - 14:35 - Eek! De Kat
Nick. - 14:45 - Rugrats
Cart. - 14:45 - The grim adventures of Billy en Mandy
Vero. - 14:50 - Lizzie McGuire
SBS6 - 14:50 - Martin
NET5 - 14:50 - International animal emergency
Ned3 - 15:00 - Tweenies

  • plakbandrol
  • Registratie: Juni 2002
  • Laatst online: 12-02 12:36
Janoz schreef op 19 mei 2004 @ 13:23:
Order by slaat op de gehele result set. Dat je een group by op zender wilt gebruiken is de juiste gedachte. De orderby werkt echter anders. Sowieso is het maar raar van MySQL dat hij dit uberhaupt pikt.
Waarjij meer op zoek naar bent is MIN(tijd.start) icm een HAVING clause.
Heb je een concreet voorbeeld? Want als ik namelijk eerst MIN() doe (op begintijd) dan pakt ie eerst de allerlaagste tijd, vervolgens moet het criteria nog komen dat de begintijd groter moet zijn dan de huidige tijd

ik heb dat al eerder geprobeerd maar toen wou het niet werken op die manier

  • n00bs
  • Registratie: Augustus 2002
  • Laatst online: 13:10

n00bs

Het is weer Zomer!

Met een dB als dit had je net zo goed 1 tabel kunnen nemen... in ieder geval join je normaal bij 2 tabellen op dezelfde key en die zijn dus zelfde type. daarnaast wat valt er nou te grouperen... je wil toch niet de zenders samenvoegen :? dan zou je maar elke zender 1 maal voorkomen, terwijl je meerdere progs hebt op verschillende tijden..., dus dat kan niet eens

  • plakbandrol
  • Registratie: Juni 2002
  • Laatst online: 12-02 12:36
P_de_B schreef op 19 mei 2004 @ 13:46:
[...]
belachelijk trouwens dat je hier geen foutmelding op krijgt :X maar het feit dat je maar 1 kolom uit de select list in je query hebt is wel de oorzaak van je probleem.
Hmm ik heb er in werkelijkheid meer, maar aangezien ik er vanuit ging dat daar het probleem niet zat, had ik hem even ingekort, dit is hem in z'n geheel
SELECT p.ref_id as ref_id, p.tijd_start,p.tijd_eind,p.genre as genre,p.omschrijving as omschrijving,
z.naam_kort as zender, z.id as zender_id, p.naam, SEC_TO_TIME( UNIX_TIMESTAMP( tijd_eind ) -
UNIX_TIMESTAMP( tijd_start ) ) AS Tijdsduur
FROM tvgids_progdb p LEFT JOIN tvgids_zenders z
ON p.zender = z.id
WHERE tijd_start > now()
group by p.zender
order by p.tijd_start

[ Voor 3% gewijzigd door plakbandrol op 19-05-2004 13:54 ]


  • plakbandrol
  • Registratie: Juni 2002
  • Laatst online: 12-02 12:36
n00bs schreef op 19 mei 2004 @ 13:51:
Met een dB als dit had je net zo goed 1 tabel kunnen nemen... in ieder geval join je normaal bij 2 tabellen op dezelfde key en die zijn dus zelfde type.
Klopt, zijn ze ook, beide INT
daarnaast wat valt er nou te grouperen... je wil toch niet de zenders samenvoegen :? dan zou je maar elke zender 1 maal voorkomen, terwijl je meerdere progs hebt op verschillende tijden..., dus dat kan niet eens
Ik wil van elke zender het eerst volgende programma

dus wat hij eigenlijk moet doen is:
1. alle resultaten groeperen in zenders
2. elke gegroepeerde zender sorteren op begintijd die hoger is dan de huidige tijd
3. van elke gegroepeerde zender de eerste nemen

zo moeilijk kan dat toch niet zijn?

[ Voor 5% gewijzigd door plakbandrol op 19-05-2004 13:59 ]


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
plakbandrol schreef op 19 mei 2004 @ 13:53:
[...]

Hmm ik heb er in werkelijkheid meer, maar aangezien ik er vanuit ging dat daar het probleem niet zat, had ik hem even ingekort, dit is hem in z'n geheel


[...]
stomme typo, ik bedoele
maar het feit dat je maar 1 kolom uit de select list in je query group by clausule hebt is wel de oorzaak van je probleem.
stel je het volgende eens voor:

code:
1
2
3
ned1    10:00   Koffietijd
ned1    12:00   Journaal
ned1    13:00   Studio Sport


Nu zeg je in je query dat je wilt groeperen op tv zender, je wilt dus maar 1 record 'ned1' terug. Je moet nu van de andere kolommen (tijd en programma) aangeven welke je terug wilt. Bijv. min(tijd) voor de eerste tijd. Dit zijn de zgn. aggregate functies, er zijn nog veel maar als MAX(), AVG() etc. etc.
De meeste databases geven een foutmelding als je dat niet doet. MySQL doet blijkbaar iets willekeurigs.

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


  • plakbandrol
  • Registratie: Juni 2002
  • Laatst online: 12-02 12:36
P_de_B schreef op 19 mei 2004 @ 13:58:

stel je het volgende eens voor:

code:
1
2
3
ned1    10:00   Koffietijd
ned1    12:00   Journaal
ned1    13:00   Studio Sport


Nu zeg je in je query dat je wilt groeperen op tv zender, je wilt dus maar 1 record 'ned1' terug. Je moet nu van de andere kolommen (tijd en programma) aangeven welke je terug wilt. Bijv. min(tijd) voor de eerste tijd. Dit zijn de zgn. aggregate functies, er zijn nog veel maar als MAX(), AVG() etc. etc.
De meeste databases geven een foutmelding als je dat niet doet. MySQL doet blijkbaar iets willekeurigs.
Ik begrijp je punt, alleen ik weet niet hoe ik dit in SQL moet vertalen

Ik moet dus eerst een group by doen op zender, en vervolgens iets in de trend van HAVING MIN(p.tijd_start)

(min omdat het eerstvolgende programma moet worden geselecteerd)

Ik zal er even mee aan de gang gaan

  • D4Skunk
  • Registratie: Juni 2003
  • Laatst online: 20-10-2025

D4Skunk

Kind of Blue

Ik kan het verkeerd voorhebben, maar kun je eens tonen wat je als resultaat wilt (ik heb de indruk dat je een kruistabel wilt ipv een group by)

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
plakbandrol schreef op 19 mei 2004 @ 14:02:
[...]
Ik begrijp je punt, alleen ik weet niet hoe ik dit in SQL moet vertalen

Ik moet dus eerst een group by doen op zender, en vervolgens iets in de trend van HAVING MIN(p.tijd_start)

(min omdat het eerstvolgende programma moet worden geselecteerd)

Ik zal er even mee aan de gang gaan
Nee HAViNG wordt gebruikt als WHERE statement maar dan voor queries met een GROUP BY.

Je moet iets als het volgende gebruiken:
code:
1
2
3
SELECT Zender, MIN(StartTijd) as StartTijd
FROM Tabel
GROUP BY Zender

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


  • plakbandrol
  • Registratie: Juni 2002
  • Laatst online: 12-02 12:36
P_de_B schreef op 19 mei 2004 @ 14:03:
[...]


Nee HAViNG wordt gebruikt als WHERE statement maar dan voor queries met een GROUP BY.

Je moet iets als het volgende gebruiken:
code:
1
2
3
SELECT Zender, MIN(StartTijd) as StartTijd
FROM Tabel
GROUP BY Zender
Volgens mij moet dat hem zijn :)

Ned1 - 14:10 - NOS-Journaal
Ned2 - 16:00 - Voetbal: 100 jaar FIFA: Frankrijk - Brazilië
Ned3 - 14:10 - Paniek in het dorp
RTL4 - 14:15 - The bold and the beautiful
RTL5 - 15:20 - RTL Z Nieuws
Yorin - 14:15 - Mad about you
Vero. - 14:15 - Beugelbekkie
SBS6 - 14:25 - Shownieuws
Nick. - 14:20 - Calimero
NET5 - 14:15 - Holiday TV
Geo. - 15:00 - The sea hunters: Leopoldville/Clayoquot: Death on Christmas Eve
Disc. - 15:00 - Ray Mears' extreme survival: Sahara/Morocco
Cart. - 14:20 - Top cat


Lijkt wel aardig te kloppen Afbeeldingslocatie: http://4aal.nl/dl/s/emot-woot.gif
Pagina: 1