[MySQL] Alleen als er 1 dorp is

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Mebus
  • Registratie: September 2006
  • Laatst online: 17-09 13:12
Ik speel het spelletje travian. Moet wat doen in m'n vrije tijd. Ze geven je de gelegenheid om wereldkaarten te maken met gegevens die je van hun website kan halen.

http://help.travian.nl/index.php?type=faq&mod=230

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE TABLE `x_world` (
  `id` int(9) unsigned NOT NULL default '0',
  `x` smallint(3) NOT NULL default '0',
  `y` smallint(3) NOT NULL default '0',
  `tid` tinyint(1) unsigned NOT NULL default '0',
  `vid` int(9) unsigned NOT NULL default '0',
  `village` varchar(20) NOT NULL default '',
  `uid` int(9) NOT NULL default '0',
  `player` varchar(20) NOT NULL default '',
  `aid` int(9) unsigned NOT NULL default '0',
  `alliance` varchar(8) NOT NULL default '',
  `population` smallint(5) unsigned NOT NULL default '0',
  UNIQUE KEY `id` (`id`)
);


Nu hebben sommige mensen dus meerdere dorpen. Wat ik wil is dat een SQL query alleen maar de records eruit haalt waarvan een speler maar 1 dorp heeft. Ik heb alleen geen flauw idee wat ik dan moet gebruiken. Dus enkele MySQL hints zijn welkom. Van de bovenste velden is het enigste veld dat uniek is is 'id'. uid kan meerdere keren voorkomen als een speler 2 of meer dorpen heeft dus waarschijnlijk moet ik het hier op uit filteren zeker?

Mebus

BABYMETAL LoL - Twitch


Acties:
  • 0 Henk 'm!

  • RAJH
  • Registratie: Augustus 2001
  • Niet online
Met een COUNT(*) en GROUP BY uid zou het moeten lukken :)

Acties:
  • 0 Henk 'm!

  • Mebus
  • Registratie: September 2006
  • Laatst online: 17-09 13:12
Dus zoiets: SELECT COUNT(1) FROM x_world GROUP BY uid

BABYMETAL LoL - Twitch


Acties:
  • 0 Henk 'm!

  • dragontje124
  • Registratie: Mei 2009
  • Laatst online: 07-09 17:50
nee
bijv:
SELECT * FROM x_world GROUP BY uid HAVING count(*)=1

en dan moet je die * tussen SELECT en FROM vervangen door alle info die je wilt hebben

(let op: alles wat je tussen SELECT en FROM zet moet je ook bij GROUP BY zetten)
dus als je bijvoorbeeld de x en y coordinaten wil hebben doe je dat zo:
SELECT x,y FROM x_world GROUP BY uid,x,y HAVING count(*)=1

[ Voor 45% gewijzigd door dragontje124 op 22-11-2009 20:59 ]


Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Mebus schreef op zondag 22 november 2009 @ 19:55:
Dus zoiets: SELECT COUNT(1) FROM x_world GROUP BY uid
Ik kan zo 2 dingen aanwijzen waardoor deze query gewoon fout is en waarop je ook gewezen zou zijn als je het even uitgeprobeerd had. [google=mysql count syntax] geeft bovendien aan hoe het wél moet. Zou je de volgende keer kunnen zoeken vóór je vragen stelt die je zelf op kan lossen? ;)
dragontje124 schreef op zondag 22 november 2009 @ 20:38:
(let op: alles wat je tussen SELECT en FROM zet moet je officieel ook bij GROUP BY zetten)
Niet alleen officieel. Dat MySQL het zo ook slikt wil niet zeggen dat het goed is.
dus als je bijvoorbeeld de x en y coordinaten wil hebben doe je dat zo:
SELECT x,y FROM x_world GROUP BY uid,x,y HAVING count(*)=1
Nee hoor, want wat doet die uid daar? Waarom select je die niet? En omdat je op x en y groupt zul je bovendien altijd elk record terug krijgen.

[ Voor 39% gewijzigd door NMe op 22-11-2009 20:53 ]

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

  • dragontje124
  • Registratie: Mei 2009
  • Laatst online: 07-09 17:50
Niet alleen officieel. Dat MySQL het zo ook slikt wil niet zeggen dat het goed is.
ja dat bedoelde ik dus eigenlijk ook :P
Nee hoor, want wat doet die uid daar? Waarom select je die niet? En omdat je op x en y groupt zul je bovendien altijd elk record terug krijgen.
omdat je toch per user groepeert en in dit voorbeeld had misschien uid wel helemaal niet nodig :P.
en ik groepeer toch eerst op uid en daarna pas op x,y?

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

dragontje124 schreef op zondag 22 november 2009 @ 20:56:
[...]

omdat je toch per user groepeert en in dit voorbeeld had misschien uid wel helemaal niet nodig :P.
en ik groepeer toch eerst op uid en daarna pas op x,y?
....en dat is van betekenis omdat...? ;) Je groepeert op uid, x én y, wat betekent dat alleen records die hetzelfde uid én dezelfde coördinaten hebben gegroepeerd worden tot één resultaat.

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

  • Manuel
  • Registratie: Maart 2008
  • Laatst online: 17-09 14:28
Ik denk dat je dan toch iets als in UID moet hebben, dan in je where clause en zo je query oplossen.

Vb:
SQL:
1
2
3
4
5
6
7
8
9
SELECT
     COUNT(uid),
     player,
     x,
     y
FROM
      tabelletje
GROUP BY
      uid;


Dit was in ieder geval het makkelijkste waarmee ik kon opkomen.. Maar even een vraag aan de TS, wat heb je inmiddels zelf al geprobeerd?

edit:
Of zo uit mijn hoofd een distinct proberen, aangezien die ervoor zorgt dat er geen dubbele resultaten tussenzitten..

[ Voor 15% gewijzigd door Manuel op 22-11-2009 21:07 ]


Acties:
  • 0 Henk 'm!

  • dragontje124
  • Registratie: Mei 2009
  • Laatst online: 07-09 17:50
NMe schreef op zondag 22 november 2009 @ 21:05:
[...]

....en dat is van betekenis omdat...? ;) Je groepeert op uid, x én y, wat betekent dat alleen records die hetzelfde uid én dezelfde coördinaten hebben gegroepeerd worden tot één resultaat.
hmm oops true xD
Manuel schreef op zondag 22 november 2009 @ 21:05:
Ik denk dat je dan toch iets als in UID moet hebben, dan in je where clause en zo je query oplossen.

Vb:
SQL:
1
2
3
4
5
6
7
8
9
SELECT
     COUNT(uid),
     player,
     x,
     y
FROM
      tabelletje
GROUP BY
      uid;


Dit was in ieder geval het makkelijkste waarmee ik kon opkomen.. Maar even een vraag aan de TS, wat heb je inmiddels zelf al geprobeerd?

edit:
Of zo uit mijn hoofd een distinct proberen, aangezien die ervoor zorgt dat er geen dubbele resultaten tussenzitten..
Daar moet je zowiezo een HAVING achter plakken om ervoor te zorgen dat alleen de users die maar 1 dorp hebben geselecteerd worden en het is geen valide SQL code omdat alles wat tussen SELECT en FROM staat ook na GROUP BY moet staan, maar zoals NMe al zei houdt Mysql daar geen rekening mee.

dus eigenlijk moet het dit worden:
SQL:
1
SELECT * FROM x_world WHERE uid IN (SELECT uid FROM x_world GROUP BY uid HAVING count(*)=1)

[ Voor 11% gewijzigd door dragontje124 op 22-11-2009 21:25 ]


Acties:
  • 0 Henk 'm!

  • Mebus
  • Registratie: September 2006
  • Laatst online: 17-09 13:12
SELECT player FROM x_world GROUP BY uid HAVING count(*)=1

Doet het perfect voor zover ik zie.

SELECT * FROM x_world WHERE uid IN (SELECT uid FROM x_world GROUP BY uid HAVING count(*)=1)

Als ik deze draai lijkt het wel alsof ie in een oneindige loop zit.. Ik kan iig weer verder! dankje:-)

BABYMETAL LoL - Twitch


Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Mebus schreef op zondag 22 november 2009 @ 21:59:
SELECT player FROM x_world GROUP BY uid HAVING count(*)=1

Doet het perfect voor zover ik zie.
Die werkt alleen omdat MySQL grouping brak heeft geïmplementeerd. Als ik jou was zou ik toch die subquery-variant proberen te fixen want dit is vragen om problemen.
Manuel schreef op zondag 22 november 2009 @ 21:05:
SQL:
1
2
3
4
5
6
7
8
9
SELECT
     COUNT(uid),
     player,
     x,
     y
FROM
      tabelletje
GROUP BY
      uid;
Elke fatsoenlijke database zal iets zeggen als dit:
Column 'player' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
;)
edit:
Of zo uit mijn hoofd een distinct proberen, aangezien die ervoor zorgt dat er geen dubbele resultaten tussenzitten..
Distinct haalt dubbele uids er niet uit, en dat is nou net iets wat wel nodig is blijkbaar. ;)

[ Voor 47% gewijzigd door NMe op 22-11-2009 22:20 ]

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

  • dragontje124
  • Registratie: Mei 2009
  • Laatst online: 07-09 17:50
NMe schreef op zondag 22 november 2009 @ 22:15:
[...]

Die werkt alleen omdat MySQL grouping brak heeft geïmplementeerd. Als ik jou was zou ik toch die subquery-variant proberen te fixen want dit is vragen om problemen.

[...]

Elke fatsoenlijke database zal iets zeggen als dit:

[...]

;)

[...]

Distinct haalt dubbele uids er niet uit, en dat is nou net iets wat wel nodig is blijkbaar. ;)
in dit geval werkt ie natuurlijk omdat van elke user die je selecteert maar 1 mogelijke row beschikbaar is (omdat ie alle users selecteert die 1 stad hebben)
maar als je meerdere rows per user opvraagt ga je inderdaad problemen krijgen

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

dragontje124 schreef op zondag 22 november 2009 @ 22:39:
[...]

in dit geval werkt ie natuurlijk omdat van elke user die je selecteert maar 1 mogelijke row beschikbaar is (omdat ie alle users selecteert die 1 stad hebben)
maar als je meerdere rows per user opvraagt ga je inderdaad problemen krijgen
Ik stel voor dat je mijn vorige posts nog eens leest want dat is dus niet het geval; je krijgt met de query die hij gaf na het fixen van die query alle records terug, met helemaal niets gegroepeerd zoals gevraagd. En met distinct gaat het ook niet werken, domweg omdat alle opgevraagde data daarvoor gelijk moet zijn (net zoals de group by dus) én dat het nog steeds records teruggeeft met meerdere worlds; alleen kun je daar niet meer aan zien dat er meerdere worlds zijn, domweg omdat je alle dubbelen eruit haalt en er eentje overhoudt. Dat is niet waar de topicstarter om vroeg.

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

Pagina: 1