/ 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 - DISTINCT med mere end én kolonne..~
Fra : Morten Jørgensen


Dato : 26-09-02 21:17

Hej,

Jeg er igang med et statistiksystem i PHP, hvor jeg har en MySQL tabel med
alle mine statistikdata i.
Der kommer så en ny række for hver sidevisning, indeholdende IP, hostname
osv.
Jeg er så igang med at lave et system som kan fremvise statistikken, hvor
jeg er nået til hvor man har valgt en måned og det så er meningen at man
skal kunne se alle dagene for måneden, med navne på dagene, hvor
weekenddagende skal være fremhævede.
Det går da også fint nok, hvor jeg bruger en DISTINCT query til at finde ud
af hvor mange dage der er i måneden.
Den ser så sådan ud:

SELECT DISTINCT dag_maaned FROM statistik WHERE maaned='$maaned' AND
aar='$aar' ORDER BY dag_maaned

Jeg skal jo så også kunne få fat i dagens navn og for ikke at skulle lave
endnu en query, da det i forvejen går rimelig langsomt, så ville jeg gerne
have hvis jeg kunne få "dag_uge" ind.

Jeg har så prøvet at lave denne:

SELECT DISTINCT dag_uge, dag_maaned FROM statistik WHERE maaned='$maaned'
AND aar='$aar' ORDER BY dag_maaned

Det hele fungerer nu som det skal, men så er spørgsmålet så bare om det er
korrekt at lave det på den måde? Hvordan foregår det i det hele taget?
Umiddelbart ville jeg jo tro at den ville finde 7 forskellige "dag_uge" og
så derved kun kunne fortsætte med at finde 7 "dag_maaned", eller har jeg
misforstået noget?

Jeg ville i øvrigt meget gerne have et link til MySQL manualen hvor der står
om DISTINCT, hvis nogen ville hjælpe mig med at findet frem til det.

Jeg har også kigget på GROUP BY, hvilket samtidig kan bruges som ORDER BY da
man kan sætte DESC bagved. Men så er spørgsmålet bare hvad der er bedst at
bruge?

--
M.v.h. Morten Jørgensen
http://bytte.startlinket.dk
StartLinket.dk´s - 1:1 BytteProgrammer



 
 
Kristian Damm Jensen (27-09-2002)
Kommentar
Fra : Kristian Damm Jensen


Dato : 27-09-02 09:47

"Morten Jørgensen" wrote:
>
> Hej,
>
> Jeg er igang med et statistiksystem i PHP, hvor jeg har en MySQL tabel med
> alle mine statistikdata i.
> Der kommer så en ny række for hver sidevisning, indeholdende IP, hostname
> osv.
> Jeg er så igang med at lave et system som kan fremvise statistikken, hvor
> jeg er nået til hvor man har valgt en måned og det så er meningen at man
> skal kunne se alle dagene for måneden, med navne på dagene, hvor
> weekenddagende skal være fremhævede.
> Det går da også fint nok, hvor jeg bruger en DISTINCT query til at finde ud
> af hvor mange dage der er i måneden.
> Den ser så sådan ud:
>
> SELECT DISTINCT dag_maaned FROM statistik WHERE maaned='$maaned' AND
> aar='$aar' ORDER BY dag_maaned
>
> Jeg skal jo så også kunne få fat i dagens navn og for ikke at skulle lave
> endnu en query, da det i forvejen går rimelig langsomt, så ville jeg gerne
> have hvis jeg kunne få "dag_uge" ind.
>
> Jeg har så prøvet at lave denne:
>
> SELECT DISTINCT dag_uge, dag_maaned FROM statistik WHERE maaned='$maaned'
> AND aar='$aar' ORDER BY dag_maaned
>
> Det hele fungerer nu som det skal, men så er spørgsmålet så bare om det er
> korrekt at lave det på den måde?

Hvis jeg forstår dig rigtigt, så ja. Omend jeg har lidt svært ved at se,
hvorfor du har behov for en distinct. Både i denne og den foregående
forespørgsel. Finder du netop ikke én række for hver dag i en given
måned i et givet år? Dvs. for september 2002 finder du 30 rækker. I så
fald er der ingen dubletter at frasortere.

> Hvordan foregår det i det hele taget?
> Umiddelbart ville jeg jo tro at den ville finde 7 forskellige "dag_uge" og
> så derved kun kunne fortsætte med at finde 7 "dag_maaned", eller har jeg
> misforstået noget?

Ja. Distinct opererer på rækkeniveau. Det vil sige at den frasorterer
række-dubletter.

> Jeg ville i øvrigt meget gerne have et link til MySQL manualen hvor der står
> om DISTINCT, hvis nogen ville hjælpe mig med at findet frem til det.

Afsnit 6.4.1.

> Jeg har også kigget på GROUP BY, hvilket samtidig kan bruges som ORDER BY da
> man kan sætte DESC bagved. Men så er spørgsmålet bare hvad der er bedst at
> bruge?

Til hvad?

"Group by" benyttes, hvis du har brug for at foretage en gruppering. Det
vil typisk sige når man skal bruge aggregate functions (er der et godt
dansk ord for det?) som max, count osv. En bivirking ved "group by" er
at output bliver sorteret. Det har fået udviklerne af MySQL til at
opfinde "group by ... desc" som forkortelse for "group by ... order by
.... desc". Jeg vil godt advare imod at bruge denne forkortelse. Man
vinder intet (eller stort set intet) ved den, men får til gengæld et
produkt, der ikke kan porteres.

Hvis formålet udelukkende er at sortere, bør man bruge "order by".

En anden bivirkning ved "group by" er, at den fjerner dubletter og
dermed kan bruges i stedet for distinct. Også dette vil jeg advare imod
- det gør det mere uklart, hvad der egentlig foregår i koden.


--
Kristian Damm Jensen | Feed the hungry at www.thehungersite.com
kristian-damm.jensen@cgey.com | Two wrongs doesn't make a right,
ICQ# 146728724 | but three lefts do.


Morten Jørgensen (27-09-2002)
Kommentar
Fra : Morten Jørgensen


Dato : 27-09-02 14:14

"Kristian Damm Jensen" <kristian-damm.jensenRE@MOVEcgey.com> wrote in
message news:3D941AF0.777D12D0@MOVEcgey.com...
> > Jeg er igang med et statistiksystem i PHP, hvor jeg har en MySQL tabel
med
> > alle mine statistikdata i.
> > Der kommer så en ny række for hver sidevisning, indeholdende IP,
hostname
> > osv.
> > Jeg er så igang med at lave et system som kan fremvise statistikken,
hvor
> > jeg er nået til hvor man har valgt en måned og det så er meningen at man
> > skal kunne se alle dagene for måneden, med navne på dagene, hvor
> > weekenddagende skal være fremhævede.
> > Det går da også fint nok, hvor jeg bruger en DISTINCT query til at finde
ud
> > af hvor mange dage der er i måneden.
> > Den ser så sådan ud:
> >
> > SELECT DISTINCT dag_maaned FROM statistik WHERE maaned='$maaned' AND
> > aar='$aar' ORDER BY dag_maaned
> >
> > Jeg skal jo så også kunne få fat i dagens navn og for ikke at skulle
lave
> > endnu en query, da det i forvejen går rimelig langsomt, så ville jeg
gerne
> > have hvis jeg kunne få "dag_uge" ind.
> >
> > Jeg har så prøvet at lave denne:
> >
> > SELECT DISTINCT dag_uge, dag_maaned FROM statistik WHERE
maaned='$maaned'
> > AND aar='$aar' ORDER BY dag_maaned
> >
> > Det hele fungerer nu som det skal, men så er spørgsmålet så bare om det
er
> > korrekt at lave det på den måde?
>
> Hvis jeg forstår dig rigtigt, så ja. Omend jeg har lidt svært ved at se,
> hvorfor du har behov for en distinct. Både i denne og den foregående
> forespørgsel. Finder du netop ikke én række for hver dag i en given
> måned i et givet år? Dvs. for september 2002 finder du 30 rækker. I så
> fald er der ingen dubletter at frasortere.

Nej, jeg skriver at der kommer en ny række for hver sidevisning, så derfor
kommer der let 10 rækker for hver time og derved omkring 240 rækker for et
helt døgn. ;)

> > Hvordan foregår det i det hele taget?
> > Umiddelbart ville jeg jo tro at den ville finde 7 forskellige "dag_uge"
og
> > så derved kun kunne fortsætte med at finde 7 "dag_maaned", eller har jeg
> > misforstået noget?
>
> Ja. Distinct opererer på rækkeniveau. Det vil sige at den frasorterer
> række-dubletter.

Du svarede ja til at jeg havde misforstået det, eller hvad?
Det med rækkeniveau må du nok forklare lidt bedre.

> > Jeg ville i øvrigt meget gerne have et link til MySQL manualen hvor der
står
> > om DISTINCT, hvis nogen ville hjælpe mig med at findet frem til det.
>
> Afsnit 6.4.1.

Der stod ikke rigtig noget jeg kunne bruge til noget. ;-(

> > Jeg har også kigget på GROUP BY, hvilket samtidig kan bruges som ORDER
BY da
> > man kan sætte DESC bagved. Men så er spørgsmålet bare hvad der er bedst
at
> > bruge?
>
> Til hvad?

Det samme som DISTINCT, da man derved kan trække andre data ud af rækken
ganske normalt, uden at skulle placere det i DISTINCT som jeg endnu ikke har
forstået hvordan kan lade sig gøre...
Jeg har nemlig også fået at vide at når man udfører en DISTINCT, så sørger
MySQL selv for at lave det om til en GROUP BY, derfor ser jeg ingen idé i at
bruge DISTINCT, hvis det er mere korrekt at bruge GROUP BY.

> "Group by" benyttes, hvis du har brug for at foretage en gruppering. Det
> vil typisk sige når man skal bruge aggregate functions (er der et godt
> dansk ord for det?) som max, count osv. En bivirking ved "group by" er
> at output bliver sorteret. Det har fået udviklerne af MySQL til at
> opfinde "group by ... desc" som forkortelse for "group by ... order by
> ... desc". Jeg vil godt advare imod at bruge denne forkortelse. Man
> vinder intet (eller stort set intet) ved den, men får til gengæld et
> produkt, der ikke kan porteres.

Det med at sætte DESC bagved synes jeg heller ikke er specielt godt... Men
jeg havde ligeledes bare fået at vide at ORDER BY ikke skulle virke samtidig
med GROUP BY!?

> Hvis formålet udelukkende er at sortere, bør man bruge "order by".

Jeg bruger altid ORDER BY, og jeg går heller ikke efter GROUP BY pga.
sorteringen.

> En anden bivirkning ved "group by" er, at den fjerner dubletter og
> dermed kan bruges i stedet for distinct. Også dette vil jeg advare imod
> - det gør det mere uklart, hvad der egentlig foregår i koden.

Igen har jeg fået at vide at DISTINCT ændres til GROUP BY af MySQL.

--
M.v.h. Morten Jørgensen
http://bytte.startlinket.dk
StartLinket.dk´s - 1:1 BytteProgrammer



Kristian Damm Jensen (27-09-2002)
Kommentar
Fra : Kristian Damm Jensen


Dato : 27-09-02 14:46

"Morten Jørgensen" wrote:
>
> "Kristian Damm Jensen" <kristian-damm.jensenRE@MOVEcgey.com> wrote in
> message news:3D941AF0.777D12D0@MOVEcgey.com...
> > > Jeg er igang med et statistiksystem i PHP, hvor jeg har en MySQL tabel
> med
> > > alle mine statistikdata i.
> > > Der kommer så en ny række for hver sidevisning, indeholdende IP,
> hostname
> > > osv.
> > > Jeg er så igang med at lave et system som kan fremvise statistikken,
> hvor
> > > jeg er nået til hvor man har valgt en måned og det så er meningen at man
> > > skal kunne se alle dagene for måneden, med navne på dagene, hvor
> > > weekenddagende skal være fremhævede.
> > > Det går da også fint nok, hvor jeg bruger en DISTINCT query til at finde
> ud
> > > af hvor mange dage der er i måneden.
> > > Den ser så sådan ud:
> > >
> > > SELECT DISTINCT dag_maaned FROM statistik WHERE maaned='$maaned' AND
> > > aar='$aar' ORDER BY dag_maaned
> > >
> > > Jeg skal jo så også kunne få fat i dagens navn og for ikke at skulle
> lave
> > > endnu en query, da det i forvejen går rimelig langsomt, så ville jeg
> gerne
> > > have hvis jeg kunne få "dag_uge" ind.
> > >
> > > Jeg har så prøvet at lave denne:
> > >
> > > SELECT DISTINCT dag_uge, dag_maaned FROM statistik WHERE
> maaned='$maaned'
> > > AND aar='$aar' ORDER BY dag_maaned
> > >
> > > Det hele fungerer nu som det skal, men så er spørgsmålet så bare om det
> er
> > > korrekt at lave det på den måde?
> >
> > Hvis jeg forstår dig rigtigt, så ja. Omend jeg har lidt svært ved at se,
> > hvorfor du har behov for en distinct. Både i denne og den foregående
> > forespørgsel. Finder du netop ikke én række for hver dag i en given
> > måned i et givet år? Dvs. for september 2002 finder du 30 rækker. I så
> > fald er der ingen dubletter at frasortere.
>
> Nej, jeg skriver at der kommer en ny række for hver sidevisning, så derfor
> kommer der let 10 rækker for hver time og derved omkring 240 rækker for et
> helt døgn. ;)

Ah! Uden et tabel-layout var det jo ikke lige til at gennemskue. Okay.

(Det er i praksis altid en god idé at poste en komplet beskrivelse af de
tabeller, der indgår i den forespørgsel man har problemer med.)

> > > Hvordan foregår det i det hele taget?
> > > Umiddelbart ville jeg jo tro at den ville finde 7 forskellige "dag_uge"
> og
> > > så derved kun kunne fortsætte med at finde 7 "dag_maaned", eller har jeg
> > > misforstået noget?
> >
> > Ja. Distinct opererer på rækkeniveau. Det vil sige at den frasorterer
> > række-dubletter.
>
> Du svarede ja til at jeg havde misforstået det, eller hvad?
> Det med rækkeniveau må du nok forklare lidt bedre.

Jeg skal prøve. Det er i virkeligheden meget simpelt.

Betragt "Tabel"

navn   dato
============
peter   01012002
peter   01012003
hans   01012002
hans   01012002

"select * from tabel" vil give alle fire rækker.

"select distinct * from tabel" vil give

navn   dato
============
peter   01012002
peter   01012003
hans   01012002

idet rækken (hans, 01012002) forekommer to gange. Den ene forekomst
bliver sorteret fra.

"select distinct navn from tabel" vil derimod give

navn   
========
peter   
hans   

idet det ikke længere er muligt at skelne mellem (peter, 01012002) og
(peter, 01012003).

Essentielt skal du forestille dig, hvad der kommer ud af din select,
hvis du ikke bruger distinct, og derefter fjerne alle dubletter.

<snip>

> > > Jeg har også kigget på GROUP BY, hvilket samtidig kan bruges som ORDER
> BY da
> > > man kan sætte DESC bagved. Men så er spørgsmålet bare hvad der er bedst
> at
> > > bruge?
> >
> > Til hvad?
>
> Det samme som DISTINCT, da man derved kan trække andre data ud af rækken
> ganske normalt, uden at skulle placere det i DISTINCT som jeg endnu ikke har
> forstået hvordan kan lade sig gøre...
> Jeg har nemlig også fået at vide at når man udfører en DISTINCT, så sørger
> MySQL selv for at lave det om til en GROUP BY, derfor ser jeg ingen idé i at
> bruge DISTINCT, hvis det er mere korrekt at bruge GROUP BY.

Man kan ikke tale om at det ene er mere korrekt end det andet. Efter min
mening er distinct bedre, hvis formålet er at fjerne dubletter og ikke
andet, simpelthen fordi det klart udtrykker hvad formålet er. Hvis jeg
ser en select med en group by, vil jeg først give mig til at lede efter
aggregat-funktionen, og - når jeg ikke finder den - overveje om
programmøren har begået en fejl. Først derefter vil det gå op for mig,
at programmøren har valgt at benytte group by til at implementere sin
egen version af distinct.

Men i øvrigt: hvis du ved, at group by gør det samme som distinct, hvori
består problemet så med at forstå, hvad distinct gør? Nå, jeg håber det
allerede er opklaret udfra ovenstående forklaring.

> > "Group by" benyttes, hvis du har brug for at foretage en gruppering. Det
> > vil typisk sige når man skal bruge aggregate functions (er der et godt
> > dansk ord for det?) som max, count osv. En bivirking ved "group by" er
> > at output bliver sorteret. Det har fået udviklerne af MySQL til at
> > opfinde "group by ... desc" som forkortelse for "group by ... order by
> > ... desc". Jeg vil godt advare imod at bruge denne forkortelse. Man
> > vinder intet (eller stort set intet) ved den, men får til gengæld et
> > produkt, der ikke kan porteres.
>
> Det med at sætte DESC bagved synes jeg heller ikke er specielt godt... Men
> jeg havde ligeledes bare fået at vide at ORDER BY ikke skulle virke samtidig
> med GROUP BY!?

Det er ganske enkelt noget vås! Med mindre der er tale om en bizar
specialitet i MySQL, som jeg ikke har hørt om tidligere.

> > Hvis formålet udelukkende er at sortere, bør man bruge "order by".
>
> Jeg bruger altid ORDER BY, og jeg går heller ikke efter GROUP BY pga.
> sorteringen.
>
> > En anden bivirkning ved "group by" er, at den fjerner dubletter og
> > dermed kan bruges i stedet for distinct. Også dette vil jeg advare imod
> > - det gør det mere uklart, hvad der egentlig foregår i koden.
>
> Igen har jeg fået at vide at DISTINCT ændres til GROUP BY af MySQL.

Ja, det er sikkert den måde MySQL i praksis udfører kommandoen. Men det
bør ikke være din første bekymring som programmør, hvad der foregår
bagved gardinet. Korrekthed og læselighed går forud for effektivitet.
(Hvis effektivitet derefter viser sig at være dårlig, kan man gå på
kompromis med læseligheden, men det er en helt anden snak.) Og da det
yderlige *ikke* er mindre effektivt at bruge den mere læselige version,
så ser jeg ingen grund til ikke at bruge den.


--
Kristian Damm Jensen | Feed the hungry at www.thehungersite.com
kristian-damm.jensen@cgey.com | Two wrongs doesn't make a right,
ICQ# 146728724 | but three lefts do.


Morten Jørgensen (27-09-2002)
Kommentar
Fra : Morten Jørgensen


Dato : 27-09-02 22:46

"Kristian Damm Jensen" <kristian-damm.jensenRE@MOVEcgey.com> wrote in
message news:3D946129.532B6973@MOVEcgey.com...
> > > > Jeg er igang med et statistiksystem i PHP, hvor jeg har en MySQL
tabel
> > med
> > > > alle mine statistikdata i.
> > > > Der kommer så en ny række for hver sidevisning, indeholdende IP,
> > hostname
> > > > osv.
> > > > Jeg er så igang med at lave et system som kan fremvise statistikken,
> > hvor
> > > > jeg er nået til hvor man har valgt en måned og det så er meningen at
man
> > > > skal kunne se alle dagene for måneden, med navne på dagene, hvor
> > > > weekenddagende skal være fremhævede.
> > > > Det går da også fint nok, hvor jeg bruger en DISTINCT query til at
finde
> > ud
> > > > af hvor mange dage der er i måneden.
> > > > Den ser så sådan ud:
> > > >
> > > > SELECT DISTINCT dag_maaned FROM statistik WHERE maaned='$maaned' AND
> > > > aar='$aar' ORDER BY dag_maaned
> > > >
> > > > Jeg skal jo så også kunne få fat i dagens navn og for ikke at skulle
> > lave
> > > > endnu en query, da det i forvejen går rimelig langsomt, så ville jeg
> > gerne
> > > > have hvis jeg kunne få "dag_uge" ind.
> > > >
> > > > Jeg har så prøvet at lave denne:
> > > >
> > > > SELECT DISTINCT dag_uge, dag_maaned FROM statistik WHERE
> > maaned='$maaned'
> > > > AND aar='$aar' ORDER BY dag_maaned
> > > >
> > > > Det hele fungerer nu som det skal, men så er spørgsmålet så bare om
det
> > er
> > > > korrekt at lave det på den måde?
> > >
> > > Hvis jeg forstår dig rigtigt, så ja. Omend jeg har lidt svært ved at
se,
> > > hvorfor du har behov for en distinct. Både i denne og den foregående
> > > forespørgsel. Finder du netop ikke én række for hver dag i en given
> > > måned i et givet år? Dvs. for september 2002 finder du 30 rækker. I så
> > > fald er der ingen dubletter at frasortere.
> >
> > Nej, jeg skriver at der kommer en ny række for hver sidevisning, så
derfor
> > kommer der let 10 rækker for hver time og derved omkring 240 rækker for
et
> > helt døgn. ;)
>
> Ah! Uden et tabel-layout var det jo ikke lige til at gennemskue. Okay.

Undskyld så, men jeg mente ellers det stod rimelig tydeligt. ;(

> (Det er i praksis altid en god idé at poste en komplet beskrivelse af de
> tabeller, der indgår i den forespørgsel man har problemer med.)
>
> > > > Hvordan foregår det i det hele taget?
> > > > Umiddelbart ville jeg jo tro at den ville finde 7 forskellige
"dag_uge"
> > og
> > > > så derved kun kunne fortsætte med at finde 7 "dag_maaned", eller har
jeg
> > > > misforstået noget?
> > >
> > > Ja. Distinct opererer på rækkeniveau. Det vil sige at den frasorterer
> > > række-dubletter.
> >
> > Du svarede ja til at jeg havde misforstået det, eller hvad?
> > Det med rækkeniveau må du nok forklare lidt bedre.
>
> Jeg skal prøve. Det er i virkeligheden meget simpelt.
>
> Betragt "Tabel"
>
> navn dato
> ============
> peter 01012002
> peter 01012003
> hans 01012002
> hans 01012002
>
> "select * from tabel" vil give alle fire rækker.
>
> "select distinct * from tabel" vil give
>
> navn dato
> ============
> peter 01012002
> peter 01012003
> hans 01012002
>
> idet rækken (hans, 01012002) forekommer to gange. Den ene forekomst
> bliver sorteret fra.
>
> "select distinct navn from tabel" vil derimod give
>
> navn
> ========
> peter
> hans
>
> idet det ikke længere er muligt at skelne mellem (peter, 01012002) og
> (peter, 01012003).
>
> Essentielt skal du forestille dig, hvad der kommer ud af din select,
> hvis du ikke bruger distinct, og derefter fjerne alle dubletter.

Det er også sådan at jeg har forstået det efter at have haft gang i en lang
diskution på www.eksperten.dk
Problemet nu er dog bare at det kun er "dag_maaned" jeg jo skal frasortere
dubletter af og "dag_uge" sådan set bare er dér fordi jeg vil kunne trække
det ud, så jeg ikke skal hen og lave 30 queries mere som finder ugedagen.
Det virker fint med "dag_uge" at sætte det med ind i DISTINCT, men det kunne
jo tænkes at man på et senere tidspunkt ville få brug for at trække det
unikke id for rækken ud, så når først dét kommer ind i DISTINCT, så er der
jo intet der er helt ens.

Hvordan skal man så bære sig ad med at få det med? Det var dér jeg tænkte på
GROUP BY, hvor jeg på www.eksperten.dk fik at vide at man ikke kunne lægge
noget i SELECT som ikke også stod i GROUP BY. Så nu er jeg på ret bar bund.

> > > > Jeg har også kigget på GROUP BY, hvilket samtidig kan bruges som
ORDER
> > BY da
> > > > man kan sætte DESC bagved. Men så er spørgsmålet bare hvad der er
bedst
> > at
> > > > bruge?
> > >
> > > Til hvad?
> >
> > Det samme som DISTINCT, da man derved kan trække andre data ud af rækken
> > ganske normalt, uden at skulle placere det i DISTINCT som jeg endnu ikke
har
> > forstået hvordan kan lade sig gøre...
> > Jeg har nemlig også fået at vide at når man udfører en DISTINCT, så
sørger
> > MySQL selv for at lave det om til en GROUP BY, derfor ser jeg ingen idé
i at
> > bruge DISTINCT, hvis det er mere korrekt at bruge GROUP BY.
>
> Man kan ikke tale om at det ene er mere korrekt end det andet. Efter min
> mening er distinct bedre, hvis formålet er at fjerne dubletter og ikke
> andet, simpelthen fordi det klart udtrykker hvad formålet er. Hvis jeg
> ser en select med en group by, vil jeg først give mig til at lede efter
> aggregat-funktionen, og - når jeg ikke finder den - overveje om
> programmøren har begået en fejl. Først derefter vil det gå op for mig,
> at programmøren har valgt at benytte group by til at implementere sin
> egen version af distinct.

Jeg tænkte bare at GROUP BY måtte være den bedste, nu da jeg har hørt at
MySQL jo laver DISTINCT om til GROUP BY... Så ser jeg nærmest DISTINCT for
en omvej. Så kan man jo lige så godt vælge den korteste vej.

> Men i øvrigt: hvis du ved, at group by gør det samme som distinct, hvori
> består problemet så med at forstå, hvad distinct gør? Nå, jeg håber det
> allerede er opklaret udfra ovenstående forklaring.

Jeg har i dag lært at det der står i DISTINCT ikke bliver afviklet i nogen
rækkefølge, men de to skal kombineres. Så er problemet bare hvordan jeg skal
få "dag_uge" med også.

> > > "Group by" benyttes, hvis du har brug for at foretage en gruppering.
Det
> > > vil typisk sige når man skal bruge aggregate functions (er der et godt
> > > dansk ord for det?) som max, count osv. En bivirking ved "group by" er
> > > at output bliver sorteret. Det har fået udviklerne af MySQL til at
> > > opfinde "group by ... desc" som forkortelse for "group by ... order by
> > > ... desc". Jeg vil godt advare imod at bruge denne forkortelse. Man
> > > vinder intet (eller stort set intet) ved den, men får til gengæld et
> > > produkt, der ikke kan porteres.
> >
> > Det med at sætte DESC bagved synes jeg heller ikke er specielt godt...
Men
> > jeg havde ligeledes bare fået at vide at ORDER BY ikke skulle virke
samtidig
> > med GROUP BY!?
>
> Det er ganske enkelt noget vås! Med mindre der er tale om en bizar
> specialitet i MySQL, som jeg ikke har hørt om tidligere.

Det er også noget vås. ;)

> > > Hvis formålet udelukkende er at sortere, bør man bruge "order by".
> >
> > Jeg bruger altid ORDER BY, og jeg går heller ikke efter GROUP BY pga.
> > sorteringen.
> >
> > > En anden bivirkning ved "group by" er, at den fjerner dubletter og
> > > dermed kan bruges i stedet for distinct. Også dette vil jeg advare
imod
> > > - det gør det mere uklart, hvad der egentlig foregår i koden.
> >
> > Igen har jeg fået at vide at DISTINCT ændres til GROUP BY af MySQL.
>
> Ja, det er sikkert den måde MySQL i praksis udfører kommandoen. Men det
> bør ikke være din første bekymring som programmør, hvad der foregår
> bagved gardinet. Korrekthed og læselighed går forud for effektivitet.
> (Hvis effektivitet derefter viser sig at være dårlig, kan man gå på
> kompromis med læseligheden, men det er en helt anden snak.) Og da det
> yderlige *ikke* er mindre effektivt at bruge den mere læselige version,
> så ser jeg ingen grund til ikke at bruge den.

Jeg har det sådan at jeg gerne vil lave det på den aller bedste måde, så jeg
ikke konstant skal tjekke mine scripts igennem for at lede efter gamle koder
og sådan, som ikke understøttes af den nyeste version.

--
M.v.h. Morten Jørgensen
http://bytte.startlinket.dk
StartLinket.dk´s - 1:1 BytteProgrammer



Kristian Damm Jensen (30-09-2002)
Kommentar
Fra : Kristian Damm Jensen


Dato : 30-09-02 11:46

"Morten Jørgensen" wrote:
>
> "Kristian Damm Jensen" <kristian-damm.jensenRE@MOVEcgey.com> wrote in
> message news:3D946129.532B6973@MOVEcgey.com...

<snip>

> > Ah! Uden et tabel-layout var det jo ikke lige til at gennemskue. Okay.
>
> Undskyld så, men jeg mente ellers det stod rimelig tydeligt. ;(

Der stod ikke et ord om hvilke rækker din tabel indeholdt, bortset fra
dem, der blev nævnt eksplicit i din select. Men lad det nu ligge.

<snip>

> Problemet nu er dog bare at det kun er "dag_maaned" jeg jo skal frasortere
> dubletter af og "dag_uge" sådan set bare er dér fordi jeg vil kunne trække
> det ud, så jeg ikke skal hen og lave 30 queries mere som finder ugedagen.

Og det går jo også fint, så længe du holder dig til en forespørgsel
inden for den sammen måned.

> Det virker fint med "dag_uge" at sætte det med ind i DISTINCT, men det kunne
> jo tænkes at man på et senere tidspunkt ville få brug for at trække det
> unikke id for rækken ud, så når først dét kommer ind i DISTINCT, så er der
> jo intet der er helt ens.

Dit problem er nok, at du forestiller dig en sammenhæng mellem en række
i dastabasetabellen og en række i dit output. Men i samme øjeblik du har
lavet en distinct eller en group by, er denne sammenhæng ikke længere
entydig.

Efter at du har foretaget en distinct, finder der ikke længere noget
række-id at referere til, og hvis du gerne vil have det med, bliver du
nødt til at forklare fra hvilken af de fem rækker der blev "foldet
sammen" til én, du ønsker at medtage række-id'et.

> Hvordan skal man så bære sig ad med at få det med? Det var dér jeg tænkte på
> GROUP BY, hvor jeg på www.eksperten.dk fik at vide at man ikke kunne lægge
> noget i SELECT som ikke også stod i GROUP BY. Så nu er jeg på ret bar bund.

Hvilket er korrekt, og grunden til at group by virker på samme måde som
distinct. Der findes systemer hvor dette ikke er et krav. Det medfører
til gengæld, at resultatet er uforudsigeligt, fordi man netop havner i
det dilemma, jeg skitserer ovenfor.

<snip>

> Jeg tænkte bare at GROUP BY måtte være den bedste, nu da jeg har hørt at
> MySQL jo laver DISTINCT om til GROUP BY... Så ser jeg nærmest DISTINCT for
> en omvej. Så kan man jo lige så godt vælge den korteste vej.

Ville du også skrive a<< frem for a*2 i et C-program? C-oversætteren vil
jo oversætte enhver multiplikation med to til en venstreskiftsoperation.

Læselighed er nøglen her.

> > Men i øvrigt: hvis du ved, at group by gør det samme som distinct, hvori
> > består problemet så med at forstå, hvad distinct gør? Nå, jeg håber det
> > allerede er opklaret udfra ovenstående forklaring.
>
> Jeg har i dag lært at det der står i DISTINCT ikke bliver afviklet i nogen
> rækkefølge, men de to skal kombineres. Så er problemet bare hvordan jeg skal
> få "dag_uge" med også.

Så længe du arbejder indenfor en måned, er der som sagt intet problem.
Jeg har også allerede i et tidligere indlæg fortalt, at den forespørgsel
du postede ville virke som beskrevet.

<snip>

> Jeg har det sådan at jeg gerne vil lave det på den aller bedste måde, så jeg
> ikke konstant skal tjekke mine scripts igennem for at lede efter gamle koder
> og sådan, som ikke understøttes af den nyeste version.

Den allerbedste måde er at benytte standarden, og at benytte
funktionerne til det de er designet til.

Både distinct og group by er en del af sql-standarden og har været det
fra starten. De vil ikke forsvinde. Men formålet med de to funktioner er
meget forskelligt.


--
Kristian Damm Jensen | Feed the hungry at www.thehungersite.com
kristian-damm.jensen@cgey.com | Two wrongs doesn't make a right,
ICQ# 146728724 | but three lefts do.



Morten Jørgensen (30-09-2002)
Kommentar
Fra : Morten Jørgensen


Dato : 30-09-02 17:31

"Kristian Damm Jensen" wrote in message
news:3D982B62.7555E10F@MOVEcgey.com...
> Der stod ikke et ord om hvilke rækker din tabel indeholdt, bortset fra
> dem, der blev nævnt eksplicit i din select. Men lad det nu ligge.

Rækker? Mener du ikke kolonner? Altså jeg skriver jo at der for hver
sidevisning kommer en ny række, indeholdende IP, hostname osv.
De indeholder ligeledes en masse dato-halløj, hvilket du kunne se på mit
script.

> > Problemet nu er dog bare at det kun er "dag_maaned" jeg jo skal
frasortere
> > dubletter af og "dag_uge" sådan set bare er dér fordi jeg vil kunne
trække
> > det ud, så jeg ikke skal hen og lave 30 queries mere som finder
ugedagen.
>
> Og det går jo også fint, så længe du holder dig til en forespørgsel
> inden for den sammen måned.

Ja, det er også derfor jeg siger det virker fint, men det kunne jo tænkes at
jeg også f.eks. gerne ville trække nogle andre data ud og så ville det jo
blive inddraget i DISTINCT´en og det ville kunne ødelægge det hele, så
derfor vil jeg gerne vide om der virkelig ikke er andre muligheder end at
lave endnu en query som opfanger dato og sådan.

> > Det virker fint med "dag_uge" at sætte det med ind i DISTINCT, men det
kunne
> > jo tænkes at man på et senere tidspunkt ville få brug for at trække det
> > unikke id for rækken ud, så når først dét kommer ind i DISTINCT, så er
der
> > jo intet der er helt ens.
>
> Dit problem er nok, at du forestiller dig en sammenhæng mellem en række
> i dastabasetabellen og en række i dit output. Men i samme øjeblik du har
> lavet en distinct eller en group by, er denne sammenhæng ikke længere
> entydig.

Jeg ved godt at det ikke giver nogen mening at trække "id" ud, men det er
idéen i det jeg siger du skal se.
Det kunne jo tænkes at der var andet jeg var interesseret i.

> Efter at du har foretaget en distinct, finder der ikke længere noget
> række-id at referere til, og hvis du gerne vil have det med, bliver du
> nødt til at forklare fra hvilken af de fem rækker der blev "foldet
> sammen" til én, du ønsker at medtage række-id'et.

Ja, men nu tænkte jeg jo bare at den skulle tage det første den finder...
Men igen er "id" jo ikke noget man kan bruge her, men du skal bare se idéen
i det.

> > Hvordan skal man så bære sig ad med at få det med? Det var dér jeg
tænkte på
> > GROUP BY, hvor jeg på www.eksperten.dk fik at vide at man ikke kunne
lægge
> > noget i SELECT som ikke også stod i GROUP BY. Så nu er jeg på ret bar
bund.
>
> Hvilket er korrekt, og grunden til at group by virker på samme måde som
> distinct. Der findes systemer hvor dette ikke er et krav. Det medfører
> til gengæld, at resultatet er uforudsigeligt, fordi man netop havner i
> det dilemma, jeg skitserer ovenfor.

Det er også derfor at jeg er gået væk fra GROUP BY nu og i steden leder
efter andre metoder.

> > Jeg tænkte bare at GROUP BY måtte være den bedste, nu da jeg har hørt at
> > MySQL jo laver DISTINCT om til GROUP BY... Så ser jeg nærmest DISTINCT
for
> > en omvej. Så kan man jo lige så godt vælge den korteste vej.
>
> Ville du også skrive a<< frem for a*2 i et C-program? C-oversætteren vil
> jo oversætte enhver multiplikation med to til en venstreskiftsoperation.
>
> Læselighed er nøglen her.

Nu kender jeg så ikke til C, men jeg har allerede indset at DISTINCT er den
bedste, efter jeg fandt ud af at GROUP BY ikke kunne tage flere kolonner
med, end der stod som GROUP BY.

> > Jeg har i dag lært at det der står i DISTINCT ikke bliver afviklet i
nogen
> > rækkefølge, men de to skal kombineres. Så er problemet bare hvordan jeg
skal
> > få "dag_uge" med også.
>
> Så længe du arbejder indenfor en måned, er der som sagt intet problem.
> Jeg har også allerede i et tidligere indlæg fortalt, at den forespørgsel
> du postede ville virke som beskrevet.

Nej, det er ikke noget problem, men igen er det "id"-eksemplet som er
problemet.

> Den allerbedste måde er at benytte standarden, og at benytte
> funktionerne til det de er designet til.
>
> Både distinct og group by er en del af sql-standarden og har været det
> fra starten. De vil ikke forsvinde. Men formålet med de to funktioner er
> meget forskelligt.

Det har jeg fundet ud af nu...
Men som sagt, hvis det kan lade sig gøre at få f.eks. "id" med på en let
måde, så fortæl mig det, eller også fortæl at det ikke kan lade sig gøre.
For så vil jeg bare lave endnu en query.

--
M.v.h. Morten Jørgensen
http://bytte.startlinket.dk
StartLinket.dk´s - 1:1 BytteProgrammer



Kristian Damm Jensen (01-10-2002)
Kommentar
Fra : Kristian Damm Jensen


Dato : 01-10-02 14:23

"Morten Jørgensen" wrote:
>
> "Kristian Damm Jensen" wrote in message
> news:3D982B62.7555E10F@MOVEcgey.com...

<snip>

> Jeg ved godt at det ikke giver nogen mening at trække "id" ud, men det er
> idéen i det jeg siger du skal se.
> Det kunne jo tænkes at der var andet jeg var interesseret i.

Det er principielt ligegyldigt. Hvis der er tale om oplysninger, der
ikke længere er entydige inden for den gruppering du hidtil har
benyttet, så er du i nøjagtig samme situation, som hvis du ville have id
hevet ud.

> > Efter at du har foretaget en distinct, finder der ikke længere noget
> > række-id at referere til, og hvis du gerne vil have det med, bliver du
> > nødt til at forklare fra hvilken af de fem rækker der blev "foldet
> > sammen" til én, du ønsker at medtage række-id'et.
>
> Ja, men nu tænkte jeg jo bare at den skulle tage det første den finder...

Nix. SQL arbejder på mængder, og der er derfor ikke nogen ordning. I
praksis vil der natuligvis findes en ordning, når du giver dig til at
kigge på disken, men den er uforudsigelig. (Og selv om den i praksis i
visse tilfælde er forudsigelig, så er det *meget* giftigt, at forlade
sig på denne ordningen. Den kunne jo ændre sig.)

Hvad du kan gøre, hvis du er ligeglad med hvilken værdi, der kommer, er
at tage den mindste (eller største).

Hvis din forespørgsel fx er

SELECT DISTINCT dag_uge, dag_maaned
FROM statistik
WHERE maaned='$maaned'
AND aar='$aar'

og du så vil have yderligere vil have et tilfældigt id, kan du i stedet
bruge

SELECT dag_uge, dag_maaned, min(id)
FROM statistik
WHERE maaned='$maaned'
AND aar='$aar'
group by dag_uge, dag_maaned

Men du er nødt til at angive eksplicit, hvilket række du vil have. SQL
kan ikke vælge en tilfældig for dig, heller ikke selv om det "bare kunne
være den første".

<snip>


--
Kristian Damm Jensen | Feed the hungry at www.thehungersite.com
kristian-damm.jensen@cgey.com | Two wrongs doesn't make a right,
ICQ# 146728724 | but three lefts do.


Morten Jørgensen (01-10-2002)
Kommentar
Fra : Morten Jørgensen


Dato : 01-10-02 16:31

"Kristian Damm Jensen" wrote in message
news:3D99A1B2.44BA5306@MOVEcgey.com...
> > Jeg ved godt at det ikke giver nogen mening at trække "id" ud, men det
er
> > idéen i det jeg siger du skal se.
> > Det kunne jo tænkes at der var andet jeg var interesseret i.
>
> Det er principielt ligegyldigt. Hvis der er tale om oplysninger, der
> ikke længere er entydige inden for den gruppering du hidtil har
> benyttet, så er du i nøjagtig samme situation, som hvis du ville have id
> hevet ud.
>
> > > Efter at du har foretaget en distinct, finder der ikke længere noget
> > > række-id at referere til, og hvis du gerne vil have det med, bliver du
> > > nødt til at forklare fra hvilken af de fem rækker der blev "foldet
> > > sammen" til én, du ønsker at medtage række-id'et.
> >
> > Ja, men nu tænkte jeg jo bare at den skulle tage det første den
finder...
>
> Nix. SQL arbejder på mængder, og der er derfor ikke nogen ordning. I
> praksis vil der natuligvis findes en ordning, når du giver dig til at
> kigge på disken, men den er uforudsigelig. (Og selv om den i praksis i
> visse tilfælde er forudsigelig, så er det *meget* giftigt, at forlade
> sig på denne ordningen. Den kunne jo ændre sig.)
>
> Hvad du kan gøre, hvis du er ligeglad med hvilken værdi, der kommer, er
> at tage den mindste (eller største).
>
> Hvis din forespørgsel fx er
>
> SELECT DISTINCT dag_uge, dag_maaned
> FROM statistik
> WHERE maaned='$maaned'
> AND aar='$aar'
>
> og du så vil have yderligere vil have et tilfældigt id, kan du i stedet
> bruge
>
> SELECT dag_uge, dag_maaned, min(id)
> FROM statistik
> WHERE maaned='$maaned'
> AND aar='$aar'
> group by dag_uge, dag_maaned
>
> Men du er nødt til at angive eksplicit, hvilket række du vil have. SQL
> kan ikke vælge en tilfældig for dig, heller ikke selv om det "bare kunne
> være den første".

Jeg tror du endelig har fået mig overbevist om at jeg ikke får brug for
andre data, som ikke er entydige...
Jeg har bare ikke kunnet finde noget eksempel, så jeg tror ikke jeg gider
arbejde mere på det.

Men du skal have tak for din hjælpsomhed.

--
M.v.h. Morten Jørgensen
http://bytte.startlinket.dk
StartLinket.dk´s - 1:1 BytteProgrammer



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

Månedens bedste
Årets bedste
Sidste års bedste