Mysql - Geabonneerde gebruiker maar één keer tellen.

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 21-09 15:23
Momenteel ben ik bezig met een project(je), en zit momenteel even vast op een bepaald punt.

Ik heb een simpele (koppel) tabel welke is: http://cl.ly/5M0x er zijn twee kolommen, `user_id` en `categories_id`, elke verwijzen naar een id in een andere tabel (`users` en `categories`).


Nu wil ik weten hoeveel leden er per categorie zijn (dit is vrij simpel te doen op deze manier):

MySQL:
1
SELECT COUNT(uc.user_id) as total FROM xs2media_users_categories as uc GROUP by uc.categorie_id


Maar nu wil ik graag dat als een gebruiker lid is van meerdere categorieën hij maar één keer wordt meegeteld voor de eerste categorie waar hij lid van is, en daarna niet meer mee wordt geteld bij de andere categorieën.
Hoe moet ik dat aanpakken?

Ik hoop dat het wat duidelijk is :)

Tweakers Time Machine Browser Extension | Chrome : Firefox


Acties:
  • 0 Henk 'm!

Verwijderd

Zoiets:
MySQL:
1
SELECT COUNT(DISTINCT uc.user_id) as total FROM xs2media_users_categories as uc GROUP by uc.categorie_id 


Dit is in mssql mogelijk als ik het goed heb, of dit in mysql ook mag weet ik niet.

Acties:
  • 0 Henk 'm!

  • mace
  • Registratie: Juni 2003
  • Laatst online: 20-09 15:25

mace

Sapere Aude

Idd met DISTINCT moet dit lukken.

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Verwijderd schreef op zondag 20 maart 2011 @ 11:50:
Zoiets:
[...]
Dit is in mssql mogelijk als ik het goed heb, of dit in mysql ook mag weet ik niet.
En hoe levert dat precies het door hem gewenste resultaat op?
ZpAz schreef op zondag 20 maart 2011 @ 11:37:
Maar nu wil ik graag dat als een gebruiker lid is van meerdere categorieën hij maar één keer wordt meegeteld voor de eerste categorie waar hij lid van is, en daarna niet meer mee wordt geteld bij de andere categorieën.
Hoe moet ik dat aanpakken?
Dus als iemand lid is van categorie 1 en van categorie 2, dan wil je dat ie in totaal 1x geteld wordt en niet bij beide los?

Hoe zou je willen bepalen welke categorie degene is waar ie bij geteld moet worden? SQL heeft geen 'volgorde' voor de record, dus als jij niet opslaat welke categorie de eerste is, dan kan wordt het heel lastig hier iets voorspelbaars bij te maken.

[ Voor 8% gewijzigd door ACM op 20-03-2011 11:54 ]


Acties:
  • 0 Henk 'm!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 21-09 15:23
Ik had het inderdaad met Distinct geprobeerd, maar dit geeft niet het gewenste resultaat. De Distinct wordt gedaan per 'group by'. Niet over de gehele select.

Dus dan kijkt hij naar unieke personen per group by (dus als een persoon vaker lid zou zijn van één categorie, dan verschijnt hij bij die categorie maar één keer). Maar ik wil graag dat hij maar in één categorie komt.

Tweakers Time Machine Browser Extension | Chrome : Firefox


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
DISTINCT helpt niet, lees de vraag nog maar een keer. :>
ZpAz schreef op zondag 20 maart 2011 @ 11:37:
Maar nu wil ik graag dat als een gebruiker lid is van meerdere categorieën hij maar één keer wordt meegeteld voor de eerste categorie waar hij lid van is, en daarna niet meer mee wordt geteld bij de andere categorieën.
En wat is jouw definitie van 'eerste categorie'?

Verwerk die definitie in je oorspronkelijke query en je bent klaar. ;) Is het bijvoorbeeld 'de categorie met laagste id', dan kan je een subquery gebruiken welke controleert dat userid niet in een andere row met lager categorie id voorkomt.

{signature}


Acties:
  • 0 Henk 'm!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 21-09 15:23
Voutloos schreef op zondag 20 maart 2011 @ 11:54:
DISTINCT helpt niet, lees de vraag nog maar een keer. :>

[...]
En wat is jouw definitie van 'eerste categorie'?

Verwerk die definitie in je oorspronkelijke query en je bent klaar. ;) Is het bijvoorbeeld 'de categorie met laagste id', dan kan je een subquery gebruiken welke controleert dat userid niet in een andere row met lager categorie id voorkomt.
Laten we dat als voorbeeld nemen, de categorie met de laagste id, dat dat de eerste is. Ik bak het zelf daarna wel om.

Tweakers Time Machine Browser Extension | Chrome : Firefox


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Nou, dan kan je het meteen zelf om gaan bakken, want de query heb ik al helemaal voorgekauwd. :)

edit:
En eens met cheatah, dikke kans dat je gebruikers niet weten hoe ze de resulterende data moeten interpreteren...

[ Voor 39% gewijzigd door Voutloos op 20-03-2011 11:58 ]

{signature}


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

ZpAz schreef op zondag 20 maart 2011 @ 11:54:
Laten we dat als voorbeeld nemen, de categorie met de laagste id, dat dat de eerste is. Ik bak het zelf daarna wel om.
De 'laagste id' (of hoogste) is de enige die je zonder wijzigingen aan je tabel aan te passen kan doen ;)

Maar dan krijg je zoiets:
SQL:
1
2
3
4
select firstcategoryid, count(*)
from 
(select userid, min(categoryid) as firstcategoryid from usercategories group by userid) as firstusers
group by firstcategoryid
Voutloos schreef op zondag 20 maart 2011 @ 11:55:
Nou, dan kan je het meteen zelf om gaan bakken, want de query heb ik al helemaal voorgekauwd. :)
De meesten zullen niet zo gauw een subquery erbij in weten te verzinnen :P

[ Voor 20% gewijzigd door ACM op 20-03-2011 11:57 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Ik vind het een onlogisch en onpraktisch probleem. Leg eens uit in welke situatie je dit zou willen?

Acties:
  • 0 Henk 'm!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 21-09 15:23
Het project is een website waar je je kan aanmelden om betaalde smsjes te ontvangen. Je kan je aanmelden in diverse categorieen. Hierdoor kan een gebruiker dus lid zijn van meedere categorieen. Per categorie kan het bedrag verschillen wat je er voor ontvangt. (Dit wordt bijgehouden en kan vanaf 5 euro worden uitbetaald).

Als adverteerder kan je aangeven onder welke categorieen je advertentie valt. Hier kan hij dus ook meerdere kiezen. Maar om er voor te zorgen dat de ontvanger (als hij lid is van meedere categorieen die gekozen zijn door de adverteerder) niet het smsje vaker krijgt wil ik dat hij maar één keer wordt gekozen.

De bovenstaande query is dan om uit te rekenen naar hoeveel personen het smsje wordt gestuurd (voor de adverteerder) en wat de kosten hiervoor voor hem zijn.
En eens met cheatah, dikke kans dat je gebruikers niet weten hoe ze de resulterende data moeten interpreteren...
Nu snap ik niet helemaal wat je hiermee bedoelt, maar misschien maakt mijn bovenstaande tekst het één en ander duidelijk.
ACM schreef op zondag 20 maart 2011 @ 11:57:

Maar dan krijg je zoiets:
SQL:
1
2
3
4
select firstcategoryid, count(*)
from 
(select userid, min(categoryid) as firstcategoryid from usercategories group by userid) as firstusers
group by firstcategoryid
Dat is inderdaad wat ik zoek.
De 'laagste id' (of hoogste) is de enige die je zonder wijzigingen aan je tabel aan te passen kan doen
De categorie_id refereert naar een rij in een andere tabel waarin informatie staat ik neem aan dat ik dmv joins gewoon op basis van die informatie kan 'sorteren' (ipv hoogste of laagste).

[ Voor 36% gewijzigd door ZpAz op 20-03-2011 12:07 ]

Tweakers Time Machine Browser Extension | Chrome : Firefox


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

ZpAz schreef op zondag 20 maart 2011 @ 12:00:
Dat is inderdaad wat ik zoek.

[...]

De categorie_id refereert naar een rij in een andere tabel waarin informatie staat ik neem aan dat ik dmv joins gewoon op basis van die informatie kan 'sorteren' (ipv hoogste of laagste).
Je kan het proberen. Officieel is er geen 'first' aggregate-functie, MySQL doet het in hun non-sql-compatible mode wel, dus je kan sorteren op de goede volgorde en dan in je selectlist 'userid, categoryid' doen (zonder aggregate-functie, wat dus eigenlijk ongeldige sql is) en dan domweg dezelfde group by en een order by op de sorteervelden.
Dat is dus een licht vieze versie die waarschijnlijk het minste werk is, of ie altijd de goede resultaten geeft is dan wel wat minder goed te voorspellen.

De officiele versie wordt wat complexer omdat je uiteindelijk per gebruiker 'de eerste' categorie moet zien te achterhalen. Dat kan vast wel met wat joins en diepere subselects, maar ik zou ook dan al gauw weer een 'limit 1' erbij zetten in zulke subselects :P

Acties:
  • 0 Henk 'm!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 21-09 15:23
Voor de geintresseerden, dit is hem geworden:

MySQL:
1
2
3
SELECT categorie_id, count(categorie_id) AS users FROM
(SELECT UC.categorie_id, C.name, max(C.staffel) AS staffel FROM xs2media_users_categories AS UC, xs2media_categories AS C WHERE C.id = UC.categorie_id GROUP BY UC.user_id) AS main_categories
GROUP BY categorie_id


Ty :)

Tweakers Time Machine Browser Extension | Chrome : Firefox


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

ACM schreef op zondag 20 maart 2011 @ 12:17:
[...]

Je kan het proberen. Officieel is er geen 'first' aggregate-functie, MySQL doet het in hun non-sql-compatible mode wel, dus je kan sorteren op de goede volgorde en dan in je selectlist 'userid, categoryid' doen (zonder aggregate-functie, wat dus eigenlijk ongeldige sql is) en dan domweg dezelfde group by en een order by op de sorteervelden.
Dat is dus een licht vieze versie die waarschijnlijk het minste werk is, of ie altijd de goede resultaten geeft is dan wel wat minder goed te voorspellen.
MySQL gaat hierin juist wel mee met de standaard die voorschrijft dat je aggregate functions moet gebruiken voor alle velden in de select list tenzij ze functioneel van elkaar afhankelijk zijn. Andere DBMS'en hebben dat nooit ondersteund, vermoedelijk omdat het behoorlijk uitnodigt to het maken van fouten zoals we hier ook zo vaak terugzien in de vele topics waar het fout wordt toegepast. MySQL ondersteunt de standaard dus juist wél op dit punt. :P In welke mate je dit clean of dirty wil noemen is dus redelijk afhankelijk van persoonlijke voorkeur.

Ik gebruik het zelf zo weinig mogelijk maar af en toe maak ik bewust de keuze om het toe te passen en zo mijn query performanter te maken. :)

'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.


Acties:
  • 0 Henk 'm!

  • wizzkizz
  • Registratie: April 2003
  • Laatst online: 25-07 07:34

wizzkizz

smile...tomorrow will be worse

Ik lees dat je het al hebt opgelost, maar voor het geval het ook werkend moet zijn/worden in andere DBMS'en en voor mijn beeldvorming mbt performance-issues toch een overweging.

Zou het ook niet mogelijk zijn om een tmp-table (user_id, category_id) te maken met category_id gelimiteerd tot de categorieën die je wilt hebben. Vervolgens met een COUNT(DISTINCT user_id) de unieke gebruikers tellen. Dat je dan zoiets krijgt:
SQL:
1
2
3
4
5
6
SELECT COUNT(DISTINCT T.user_id)
FROM 
    (SELECT user_id, category_id 
     FROM xs2media_users_categories
     WHERE category_id IN( 1,2,3 )
    ) as T

Voor zover ik zie zijn hier geen performance issues (want je hebt toch index op user_id en category_id). Of sla ik de plank hier behoorlijk mis?

Make it idiot proof and someone will make a better idiot.
Real programmers don't document. If it was hard to write, it should be hard to understand.


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 21-09 02:21

Janoz

Moderator Devschuur®

!litemod

ZpAz schreef op zondag 20 maart 2011 @ 12:00:
Als adverteerder kan je aangeven onder welke categorieen je advertentie valt. Hier kan hij dus ook meerdere kiezen. Maar om er voor te zorgen dat de ontvanger (als hij lid is van meedere categorieen die gekozen zijn door de adverteerder) niet het smsje vaker krijgt wil ik dat hij maar één keer wordt gekozen.
Maar op welke manier gaat deze query je dan helpen? Als pietje in cat 1 2 en 3 zit, adverteerder kiest 2 en 3 dan wordt pietje niet meegeteld omdat hij al bij 1 meegeteld was.

Het lijkt me dat je beter je eigen verhaaltje nog eens kunt lezen en op basis daarvan een query maken. Selecteer alle unieke gebruikers die in dit setje van categorieen zit. GROEP BY weg en een IN erbij en klaar.

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!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 21-09 15:23
Janoz schreef op maandag 21 maart 2011 @ 11:51:
[...]

Maar op welke manier gaat deze query je dan helpen? Als pietje in cat 1 2 en 3 zit, adverteerder kiest 2 en 3 dan wordt pietje niet meegeteld omdat hij al bij 1 meegeteld was.

Het lijkt me dat je beter je eigen verhaaltje nog eens kunt lezen en op basis daarvan een query maken. Selecteer alle unieke gebruikers die in dit setje van categorieen zit. GROEP BY weg en een IN erbij en klaar.
Ik zou de query kunnen gebruiken met 'limieten' op de geselecteerde query (where categorie_id=y OR categorie_id=x). Denk dat dat wel zou moeten werken.

edit:

Maar wat als de adverteerder nog geen categorie heeft geselecteerd, dan werkt het niet goed. Want dan zijn er 'minder leden' per categorie, en als hij het wel selecteerd kan het ineens anders zijn...

Hier moet ik nog maar eens over nadenken.

[ Voor 16% gewijzigd door ZpAz op 21-03-2011 20:09 ]

Tweakers Time Machine Browser Extension | Chrome : Firefox


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Eigenlijk doe je gewoon moeilijk. :P Toon bij alle categorieën het aantal gebruikers, en vervolgens over de gehele selectie een enkel total van het aantal verschillende gebruikers. Klaar.

Meer details boeien niet, of als iemand tijd te veel heeft kan hij een uur met de selectie spelen. :P

{signature}


Acties:
  • 0 Henk 'm!

  • wizzkizz
  • Registratie: April 2003
  • Laatst online: 25-07 07:34

wizzkizz

smile...tomorrow will be worse

ZpAz schreef op maandag 21 maart 2011 @ 20:00:
edit:

Maar wat als de adverteerder nog geen categorie heeft geselecteerd, dan werkt het niet goed. Want dan zijn er 'minder leden' per categorie, en als hij het wel selecteerd kan het ineens anders zijn...

Hier moet ik nog maar eens over nadenken.
Kijk nog eens naar mijn query in wizzkizz in "Mysql - Geabonneerde gebruiker maar één ...".Volgens mij doet dit precies wat je wilt namelijk en het is ook wat Janoz zegt. Je haalt namelijk alle gebruikers op die lid zijn van een bepaalde categorie (of 2, of 3 of n categorieën) en bepaalt vervolgens van die selectie hoeveel unieke gebruikers het zijn. Geef je 1 categorie op werkt dat ook.

Met die query kun je vervolgens doen wat Voutloos zegt en mij ook de way to go lijkt.

Gegeven de case die je aangeeft, voldoet het imho aan je eisen voor het selecteren van de (aantallen) gebruikers.

[ Voor 4% gewijzigd door wizzkizz op 21-03-2011 22:05 ]

Make it idiot proof and someone will make a better idiot.
Real programmers don't document. If it was hard to write, it should be hard to understand.


Acties:
  • 0 Henk 'm!

  • moozzuzz
  • Registratie: Januari 2005
  • Niet online
Voutloos schreef op maandag 21 maart 2011 @ 21:44:
Eigenlijk doe je gewoon moeilijk. :P Toon bij alle categorieën het aantal gebruikers, en vervolgens over de gehele selectie een enkel total van het aantal verschillende gebruikers. Klaar.

Meer details boeien niet, of als iemand tijd te veel heeft kan hij een uur met de selectie spelen. :P
Volgens mij is de eenvoud van de aangedragen oplossing het probleem voor de TS omdat zijn specs nog in de knoop zitten. Wat kost immers een smsje naar een gebruiker ingeschreven in categorie A (kost a) en categorie B (cost b) (er van uit gaande dat de adverteerder beide categorien wil aanspreken; anders is er immers geen telprobleem)? Ik zie overigens een opportuniteit in het concept:
- aanrekenen categorien zonder rekening te houden met het "unieke gebruikers" probleem
- verzenden sms naar gebruikers volgens goedkoopste categorie
offtopic:
Moet ik misschien pattenteren ;-)

Acties:
  • 0 Henk 'm!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 21-09 15:23
- verzenden sms naar gebruikers volgens goedkoopste categorie
Het is de bedoeling dat het aan de hand van de duurste categorie gaat. Heb het momenteel zo: http://cl.ly/5QW5

Als je categorieën selecteert dan verschijnt de tabel eronder met de prijzen. Alleen selecteert hij nu op verkeerde waardes (fruit is immers goedkoper als studenten), heb nu 4 proefleden die alle 4 lid zijn van zowel studenten als fruit.

De query die gebruikt wordt is:

code:
1
SELECT categorie_id, count(categorie_id) AS users FROM (SELECT UC.categorie_id, C.name, max(C.staffel) AS staffel FROM xs2media_users_categories AS UC, xs2media_categories AS C WHERE C.id = UC.categorie_id AND (C.id='2' OR C.id='11' ) GROUP BY UC.user_id) AS main_categories GROUP BY categorie_id


Maar als ik de subquery uitvoer (daar zit sowieso al een fout in (klikje) wordt elke 'staffel' 11 (die van studenten). Hoe hoger de staffel, hoe duurder het smsje.
code:
1
2
3
4
5
6
SELECT COUNT(DISTINCT T.user_id) 
FROM  
    (SELECT user_id, category_id  
     FROM xs2media_users_categories 
     WHERE category_id IN( 1,2,3 ) 
    ) as T
Volgens mij krijg ik nu één waarde terug met het aantal unieke personen over meerdere categorieën, niet helemaal wat ik zoek. Elke categorie heeft een eigen prijs, dus ik kan niet totaal aantal personen * prijs doen over meerdere categorieën.

edit:

Met de volgende query:

code:
1
SELECT max(C.staffel), C.name FROM xs2media_categories AS C


Verwacht ik dat hij een C.name pakt die bij de C.staffel hoort, maar dat doet hij niet? Hij pakt wel de hoogste staffel uit de tabel, maar de eerste name uit de tabel, terwijl die niet de hoogste staffel heeft.

Het resultaat van de query is namelijk:

Afbeeldingslocatie: http://f.cl.ly/items/2Y0q1B3L2N2A3f001Y2F/Screen%20shot%202011-03-22%20at%2010.43.04.png

Terwijl de tabel inhoud is:

Afbeeldingslocatie: http://f.cl.ly/items/0v2j2q31012Z2I142P0K/Screen%20shot%202011-03-22%20at%2010.43.13.png

Ik zou als uitkomst dan verwachten - 11 Studenten. Immers is dat de eerste hit met de 'max' staffel.

edit2: Deze link legt dat uit, eens kijken. http://www.plus2net.com/sql_tutorial/sql_max.php

[ Voor 46% gewijzigd door ZpAz op 22-03-2011 11:03 ]

Tweakers Time Machine Browser Extension | Chrome : Firefox


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 21-09 02:21

Janoz

Moderator Devschuur®

!litemod

Zo werken aggregerende functies niet. Check onze FAQ anders even bij het stukje group by,

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!

  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 19-09 10:19
(klein puntje, het enkelvoud van categories is category).

~ Mijn prog blog!


Acties:
  • 0 Henk 'm!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 21-09 15:23
@hierboven, ja ik zag het idd ;)

Tweakers Time Machine Browser Extension | Chrome : Firefox


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

roy-t schreef op dinsdag 22 maart 2011 @ 11:57:
(klein puntje, het enkelvoud van categories is category).
Hij heeft ook name enerzijds en staffel anderzijds, dus echt voor een taal kiezen is er toch niet bij. :P

'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.


Acties:
  • 0 Henk 'm!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 21-09 15:23
NMe schreef op dinsdag 22 maart 2011 @ 12:50:
[...]

Hij heeft ook name enerzijds en staffel anderzijds, dus echt voor een taal kiezen is er toch niet bij. :P
Ik weet niet eens wat een staffel is, tenminste enkel in dit project nu. En had er nog nooit van gehoord, maar inderdaad, de naamgeving is niet je van het.

Tweakers Time Machine Browser Extension | Chrome : Firefox


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

NMe schreef op maandag 21 maart 2011 @ 11:23:
MySQL gaat hierin juist wel mee met de standaard die voorschrijft dat je aggregate functions moet gebruiken voor alle velden in de select list tenzij ze functioneel van elkaar afhankelijk zijn. Andere DBMS'en hebben dat nooit ondersteund, vermoedelijk omdat het behoorlijk uitnodigt to het maken van fouten zoals we hier ook zo vaak terugzien in de vele topics waar het fout wordt toegepast. MySQL ondersteunt de standaard dus juist wél op dit punt. :P
Mij is niet duidelijk wat je precies stelt dat de SQL-specificatie voorschrijft en in hoeverre MySQL dat ondersteund? Helaas is de SQL-specificatie zo onleesbaar geschreven, dat ik geen flauw idee heb waar ik eenvoudig kan lezen hoe een select-list icm een group-by moet werken...

Maar vziw is dit incorrect SQL:
SQL:
1
SELECT a, b FROM tabel GROUP BY a


En als ik MySQL zelf mag geloven is dat inderdaad een afwijking:
MySQL extends the use of GROUP BY to permit selecting fields that are not mentioned in the GROUP BY clause.
Bovenstaande query levert je in PostgreSQL een foutmelding op, maar in MySQL een resultaatset waarbij je voor elke unieke a 'een b' (meestal de eerste die ie tegenkwam) ziet.

Ik weet niet wat jij bedoeld met 'functioneel van elkaar afhankelijk'? Zoiets wellicht?
SQL:
1
SELECT a, b, a+b as c FROM tabel GROUP BY a, b


Dat is inderdaad wel geldige SQL en wordt ook toegelaten in PostgreSQL.

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

'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.


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Ah, op die manier. Je zou in theorie bij een PK-group dus alle non-pk velden weg kunnen laten omdat die functioneel afhankelijk zijn van de PK.

Desalniettemin is dat niet relevant voor deze situatie. De categoryid's waren juist wel allemaal verschillend en niet functioneel afhankelijk van de grouped kolom, en de 'eerste die je tegenkomt gebruiken'-situatie is iets dat MySQL dus wel met hun afwijkend gedrag (niet standaard conformerend in dit geval ;) ) aanbiedt, maar vziw niet zomaar in SQL gerealiseerd kan worden.

Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

Ik heb dat artikel vaker gezien door de jaren en moet er nog altijd van grinniken. In short: "hoi we weten dat onze functionaliteit extreem kut en slecht is maar we gaan nu een banaan proberen recht te praten omdat onze fundamentele designbug in extreem uitzonderlijke gevallen wel acceptabele en standaardconforme resultaten oplevert".

Ook leuk dat ze specifiek met Oracle vergelijken en vingerwijzen omdat die geen heldere foutmelding geeft, en ze dus beter fundamenteel fout gedrag kunnen toestaan. MS SQL Server geeft al een jaar of 10:
Msg 8120, Level 16, State 1, Line 1
Column 'Table.ColumnName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Hoezo onduidelijke foutmeldingen? ;)

[ Voor 29% gewijzigd door curry684 op 24-03-2011 12:19 ]

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • jbdeiman
  • Registratie: September 2008
  • Laatst online: 13:21
ZpAz schreef op dinsdag 22 maart 2011 @ 10:21:
[...]


Het is de bedoeling dat het aan de hand van de duurste categorie gaat. Heb het momenteel zo: http://cl.ly/5QW5

Als je categorieën selecteert dan verschijnt de tabel eronder met de prijzen. Alleen selecteert hij nu op verkeerde waardes (fruit is immers goedkoper als studenten), heb nu 4 proefleden die alle 4 lid zijn van zowel studenten als fruit.
Niet handig lijkt me, wel leuk voor de adverteerders. Ik begrijp dat een gebruiker zich op meerdere groepen in kan schrijven, maar wat is dan duurste categorie?
Daarbij is het dan ook nog eens zo als je een advertentie aan 3 categorieën hebt hangen, waarin heel verschillende gebruikers (niet 1 gebruiker hetzelfde) en de totalen gebruikers per categorie liggen zo:
- Cat1: 90
- Cat2: 89
- Cat3: 91
Dan heeft degene die de sms wil versturen dus feitelijk 270 sms'jes voor de prijs van 91. Iets zegt mij dat hier geen rekening mee is gehouden in je businessmodel.
Tevens ga ik ervanuit dat een adverteerder zelf aangeeft in welke categorieën hij/ zij wil adverteren met een bepaalde advertentie? Omdat ik als adverteerder per categorie kan zien hoeveel gebruikers, kan ik heel diverse categorieën kiezen, om zodoende een grotere groep verschillende mensen te bereiken, voor een redelijk lage prijs.
ZpAz schreef op dinsdag 22 maart 2011 @ 10:21:
[...]
De query die gebruikt wordt is:

code:
1
SELECT categorie_id, count(categorie_id) AS users FROM (SELECT UC.categorie_id, C.name, max(C.staffel) AS staffel FROM xs2media_users_categories AS UC, xs2media_categories AS C WHERE C.id = UC.categorie_id AND (C.id='2' OR C.id='11' ) GROUP BY UC.user_id) AS main_categories GROUP BY categorie_id


Maar als ik de subquery uitvoer (daar zit sowieso al een fout in (klikje) wordt elke 'staffel' 11 (die van studenten). Hoe hoger de staffel, hoe duurder het smsje.


[...]


Volgens mij krijg ik nu één waarde terug met het aantal unieke personen over meerdere categorieën, niet helemaal wat ik zoek. Elke categorie heeft een eigen prijs, dus ik kan niet totaal aantal personen * prijs doen over meerdere categorieën.

edit:

Met de volgende query:

code:
1
SELECT max(C.staffel), C.name FROM xs2media_categories AS C


Verwacht ik dat hij een C.name pakt die bij de C.staffel hoort, maar dat doet hij niet? Hij pakt wel de hoogste staffel uit de tabel, maar de eerste name uit de tabel, terwijl die niet de hoogste staffel heeft.

Het resultaat van de query is namelijk:

[afbeelding]

Terwijl de tabel inhoud is:

[afbeelding]

Ik zou als uitkomst dan verwachten - 11 Studenten. Immers is dat de eerste hit met de 'max' staffel.

edit2: Deze link legt dat uit, eens kijken. http://www.plus2net.com/sql_tutorial/sql_max.php
Elke categorie een eigen prijs is ook niet eerlijk, omdat je bijna niet feitelijk denk ik dat je moet kijken naar het totale bereik van een advertentie/ adverteerder, deze bepaal je inderdaad door het "totaal aantal unieke gebruikers" in de groep categoriën van de sms.
Mij lijkt het ook handiger als je een soort van "korting" geeft op sms-jes als men naar meerdere gebruikers in 1 maal wil sms-en.

Bijv: - 100 sms'jes, 5 euro, 200 sms'jes 9 euro enz.... Dat lijkt me pretttiger en eenduidiger voor iedereen.

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

curry684 schreef op donderdag 24 maart 2011 @ 12:14:
[...]

Ik heb dat artikel vaker gezien door de jaren en moet er nog altijd van grinniken. In short: "hoi we weten dat onze functionaliteit extreem kut en slecht is maar we gaan nu een banaan proberen recht te praten omdat onze fundamentele designbug in extreem uitzonderlijke gevallen wel acceptabele en standaardconforme resultaten oplevert".
Ik zal niet zeggen dat ik het vaak gebruik, maar ik heb het in het verleden wel eens toegepast (voor privéprojectjes, don't worry :+) op plekken waar het mijn queries eenvoudiger maakte. Maar dan wel met in het achterhoofd dat het wel eens zou kunnen gaan breken als MySQL het fixt. :P

'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.


Acties:
  • 0 Henk 'm!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 21-09 15:23
jbdeiman schreef op donderdag 24 maart 2011 @ 12:23:
[...]


Niet handig lijkt me, wel leuk voor de adverteerders. Ik begrijp dat een gebruiker zich op meerdere groepen in kan schrijven, maar wat is dan duurste categorie?
Daarbij is het dan ook nog eens zo als je een advertentie aan 3 categorieën hebt hangen, waarin heel verschillende gebruikers (niet 1 gebruiker hetzelfde) en de totalen gebruikers per categorie liggen zo:
- Cat1: 90
- Cat2: 89
- Cat3: 91

Dan heeft degene die de sms wil versturen dus feitelijk 270 sms'jes voor de prijs van 91. Iets zegt mij dat hier geen rekening mee is gehouden in je businessmodel.
Nee, ik wil juist het unieke aantal ingeschreven personen hebben. Als die 90, 89 en 91 allemaal uniek zijn zal er voor 270 smsjes betaald worden. Maar als cat3 bijvoorbeeld 10ct per sms kost en Cat2 15ct per sms, dan zal er dus 91*10ct + 89*15ct betaald moeten worden.

Als iemand dan lid is van zowel cat2 als 3, dan zal er voor de duurste betaald moeten worden (15ct).
Tevens ga ik ervanuit dat een adverteerder zelf aangeeft in welke categorieën hij/ zij wil adverteren met een bepaalde advertentie? Omdat ik als adverteerder per categorie kan zien hoeveel gebruikers, kan ik heel diverse categorieën kiezen, om zodoende een grotere groep verschillende mensen te bereiken, voor een redelijk lage prijs.
Zie mijn bovenstaande, daarnaast worden de smsjes eerst ook nog gecontroleerd voordat ze verzonden worden.
Elke categorie een eigen prijs is ook niet eerlijk, omdat je bijna niet feitelijk denk ik dat je moet kijken naar het totale bereik van een advertentie/ adverteerder, deze bepaal je inderdaad door het "totaal aantal unieke gebruikers" in de groep categoriën van de sms.
Mij lijkt het ook handiger als je een soort van "korting" geeft op sms-jes als men naar meerdere gebruikers in 1 maal wil sms-en.

Bijv: - 100 sms'jes, 5 euro, 200 sms'jes 9 euro enz.... Dat lijkt me pretttiger en eenduidiger voor iedereen.
Het is niet mijn project en dit zijn de wensen die ik doorgespeeld kreeg. Ik had er al met de persoon over gepraat, maar dit is wat ie wil.

Tweakers Time Machine Browser Extension | Chrome : Firefox


Acties:
  • 0 Henk 'm!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 21-09 15:23
Hmm, kreeg niet een query aan de praat die de data teruggaf die ik wilde, dus heb er maar voor gekozen om elke user van de geselecteerde categorie-en op te halen en deze in php om te vormen naar de resultaten die ik wilde hebben.

edit: Sorry, dubbelpost, mag gemerged worden als dat kan.

[ Voor 14% gewijzigd door ZpAz op 24-03-2011 20:16 ]

Tweakers Time Machine Browser Extension | Chrome : Firefox

Pagina: 1