/ Forside / Teknologi / Udvikling / SQL / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
SQL
#NavnPoint
pmbruun 1704
niller 962
fehaar 730
Interkril.. 701
ellebye 510
pawel 510
rpje 405
pete 350
gibson 320
10  smorch 260
Mysql Group by problem
Fra : news.tele.dk


Dato : 27-01-05 10:55

Hej NG

Jeg har lidt problemer med brugen af group by.

Jeg har en tabel der er en slags log over besøgende på min server.
den indeholder blandt andet referer.

Når jeg vil tælle hvilke sites der oftest sender folk til mit site bruger
jeg:

SELECT `referer`,COUNT(*) as `antal` FROM `visit` GROUP BY `referer` order
by antal desc
den giver selvfølgelig en pæn liste over referers sorteret efter antal.
Problemet er at hvis der er refereret fra www.domæne.dk/?id=2 , 4 gange og
www.domæne.dk/?id=3 , 10 gange bliver de grupperet hver for sig, og jeg
ønsker at gruppere dem sammen. med det samlede antal:

referer antal
www.domæne.dk 14

Nogle idéer ?

Martin



 
 
Jens Gyldenkærne Cla~ (27-01-2005)
Kommentar
Fra : Jens Gyldenkærne Cla~


Dato : 27-01-05 12:54

news.tele.dk skrev:

> Problemet er at hvis der er refereret fra www.domæne.dk/?id=2 , 4 gange og
> www.domæne.dk/?id=3 , 10 gange bliver de grupperet hver for sig, og jeg
> ønsker at gruppere dem sammen. med det samlede antal:

Brug strengfunktioner til at fjerne alt efter /-tegnet. Jeg kender ikke
mysql, så jeg ved ikke hvilke funktioner du har til rådighed, men der er
givetvis både en form af instr (find /-tegnet) og left (beskær feltet)

Du kan enten fjerne ekstraoplysningerne en gang for alle (UPDATE) eller
også bare gøre det i din grupperingsforespørgsel.

--
Jens Gyldenkærne Clausen
Svar venligst under det du citerer, og citer kun det der er
nødvendigt for at forstå dit svar i sammenhængen. Se hvorfor og
hvordan på http://usenet.dk/netikette/citatteknik.html

Jeppe Uhd (27-01-2005)
Kommentar
Fra : Jeppe Uhd


Dato : 27-01-05 13:18

news.tele.dk wrote:
> Hej NG
>
> Jeg har lidt problemer med brugen af group by.
>
> Jeg har en tabel der er en slags log over besøgende på min server.
> den indeholder blandt andet referer.
>
> Når jeg vil tælle hvilke sites der oftest sender folk til mit site
> bruger jeg:
>
> SELECT `referer`,COUNT(*) as `antal` FROM `visit` GROUP BY `referer`
> order by antal desc
> den giver selvfølgelig en pæn liste over referers sorteret efter
> antal. Problemet er at hvis der er refereret fra www.domæne.dk/?id=2
> , 4 gange og www.domæne.dk/?id=3 , 10 gange bliver de grupperet hver
> for sig, og jeg ønsker at gruppere dem sammen. med det samlede antal:
>
> referer antal
> www.domæne.dk 14
>
> Nogle idéer ?

Noget i retning af: (utestet)

SELECT LEFT(`referer`,INSTR(CONCAT(`referer`,'/'),'/')-1) AS
`ref`,COUNT(`referer`) as `antal` FROM `visit` GROUP BY `ref` ORDER BY
`antal` DESC;

Vil dog give mange hits på "http:" hvis `referer` er sat ind som
http://www.domæne.dk

Grunden til CONCAT er for at være sikker på at der er -mindst- et "/" i
strengen...

Husk at have en index på referer for at gøre det hurtigere...

--
MVH Jeppe Uhd - NX http://nx.dk
Webhosting for nørder og andet godtfolk



Peter Brodersen (27-01-2005)
Kommentar
Fra : Peter Brodersen


Dato : 27-01-05 15:45

On Thu, 27 Jan 2005 13:18:15 +0100, "Jeppe Uhd" <nnewsnospam@nx.dk>
wrote:

>Husk at have en index på referer for at gøre det hurtigere...

Et index vil ikke ændre på noget her. Alle referer-felter skal i den
situation alligevel "manuelt" behandles, idet referer-feltet indgår
inde i en funktion.

MySQL bruger ikke index ved indekserede felter som del af funktioner,
så LEFT(indekseret_felt, n) gør ikke brug af index. Det gør fx
(indekseret_felt LIKE 'abc%') derimod.

Men selv hvis LEFT() gjorde brug af index, vil CONCAT(`referer`,'/')
alligevel resultere i at alle rækker skulle slås op.

Det er ret let at efterprøve, fx for en navnetabel:
explain SELECT * FROM names WHERE CONCAT(firstname,"x") = 'Peterx';

--
- Peter Brodersen

Jeppe Uhd (27-01-2005)
Kommentar
Fra : Jeppe Uhd


Dato : 27-01-05 16:20

Peter Brodersen wrote:
> On Thu, 27 Jan 2005 13:18:15 +0100, "Jeppe Uhd" <nnewsnospam@nx.dk>
> wrote:
>
>> Husk at have en index på referer for at gøre det hurtigere...
>
> Et index vil ikke ændre på noget her. Alle referer-felter skal i den
> situation alligevel "manuelt" behandles, idet referer-feltet indgår
> inde i en funktion.
>
> MySQL bruger ikke index ved indekserede felter som del af funktioner,
> så LEFT(indekseret_felt, n) gør ikke brug af index. Det gør fx
> (indekseret_felt LIKE 'abc%') derimod.
>
> Men selv hvis LEFT() gjorde brug af index, vil CONCAT(`referer`,'/')
> alligevel resultere i at alle rækker skulle slås op.
>
> Det er ret let at efterprøve, fx for en navnetabel:
> explain SELECT * FROM names WHERE CONCAT(firstname,"x") = 'Peterx';

explain select left(concat('#',name),2) as ref,count(name) as antal from
clients group by ref order by antal;
+---------+-------+---------------+--------+---------+------+------+--------
--------------------------------------+
| table | type | possible_keys | key | key_len | ref | rows | Extra
|
+---------+-------+---------------+--------+---------+------+------+--------
--------------------------------------+
| clients | index | NULL | idname | 104 | NULL | 1035 | Using
index; Using temporary; Using filesort |
+---------+-------+---------------+--------+---------+------+------+--------
--------------------------------------+
1 row in set (0.00 sec)

Ja, den bruger jo godt nok index'et ifølge den selv... At den så også bruger
temporary er lidt slemt, men nok desværre umuligt at undgå...

--
MVH Jeppe Uhd - NX http://nx.dk
Webhosting for nørder og andet godtfolk



Peter Brodersen (27-01-2005)
Kommentar
Fra : Peter Brodersen


Dato : 27-01-05 16:57

On Thu, 27 Jan 2005 16:19:40 +0100, "Jeppe Uhd" <nnewsnospam@nx.dk>
wrote:

>Ja, den bruger jo godt nok index'et ifølge den selv... At den så også bruger
>temporary er lidt slemt, men nok desværre umuligt at undgå...

"Using index" betyder ikke, at den bruger indexet i forbindelse med at
begrænse opslaget, men at den ikke behøver at kigge i datafilen for at
trække resultatet ud - fordi de(t) felt(er), du trækker ud, står i
index-filen i forvejen:

http://dev.mysql.com/doc/mysql/en/explain.html
"The column information is retrieved from the table using only
information in the index tree without having to do an additional seek
to read the actual row. This strategy can be used when the query uses
only columns that are part of a single index."

Det er en ret lille optimering i den forbindelse. Det relevante er, at
den skal kigge alle dine 1035 rækker igennem.


Grundlæggende set handler det nok om hvor ofte, der foretages de
udtræk. Hvis det blot er sjældne/individuelle udtræk, der kan ændre
sig (fx at man en dag blot vil skære querystring'en fra, eller tillade
ét niveau af mapper), så kan det let være overkill at skulle
fragmentere URLs af den grund og bruge en masse tid på det i
insert-fasen - i forhold til måske at vente et minuts tid, når man
skal lave det enkelte udtræk.

--
- Peter Brodersen

Jeppe Uhd (27-01-2005)
Kommentar
Fra : Jeppe Uhd


Dato : 27-01-05 17:41

Peter Brodersen wrote:
> On Thu, 27 Jan 2005 16:19:40 +0100, "Jeppe Uhd" <nnewsnospam@nx.dk>
> wrote:
>
>> Ja, den bruger jo godt nok index'et ifølge den selv... At den så
>> også bruger temporary er lidt slemt, men nok desværre umuligt at
>> undgå...
>
> "Using index" betyder ikke, at den bruger indexet i forbindelse med at
> begrænse opslaget, men at den ikke behøver at kigge i datafilen for at
> trække resultatet ud - fordi de(t) felt(er), du trækker ud, står i
> index-filen i forvejen:

Ja, og hvis man har en stor tabel med mere end blot referer kunne det jo
være en fordel at den kun skulle kigge i index'et...

--
MVH Jeppe Uhd - NX http://nx.dk
Webhosting for nørder og andet godtfolk



Søg
Reklame
Statistik
Spørgsmål : 177513
Tips : 31968
Nyheder : 719565
Indlæg : 6408606
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste