webForumDet fria alternativet

GROUP BY och flera värden

11 svar · 554 visningar · startad av Troxy

TroxyMedlem sedan mars 20041 505 inlägg
#1

Det är svårt det där med rubriker på trådar... x(

Nåväl, jag använder SQL Server 2000.
I en SQL-fråga så grupperar jag efter ett ID-fält, där samma värde förekommer flera gånger. Detta bildar ju då grupper som innehåller flera antal poster.

Utöver detta ID-fält, så hämtar jag även lite andra textfält som har snarlika värden, men ändå inte dubletter.
Men eftersom textfälten finns med i min SELECT så vill servern att jag grupperar även på textfälten.
Men då blir det dubletter i ID-fältet och det vill jag inte...

Så nu undrar jag om det finns någon Aggregate-funktion som bara plockar det översta värdet från en kollumn i gruppen så jag slipper gruppera det.
MAX fungerar inte riktigt eftersom det inte är nummer och då verkar den plocka lite hur som helst.

Hoppas ni förstår min förklaring...
Tacksam för svar.

LarsGMedlem sedan dec. 200012 464 inlägg
#2

Exemplifiera med datainnehåll och förväntat resultat.

Att säga översta posten är inte relevant i mängdsammanhang.

TroxyMedlem sedan mars 20041 505 inlägg
#3

Jo jag vet att det låter luddigt. Ska försöka ge tabellexempel senare.

Men det är snarlika resultat som jag tvingas gruppera.
I textkollumnerna kan det t.ex. finnas både "DVD-movie", "DVD movie".
Och då blir det två poster av detta eftersom det inte är exakt samma värde.
Då vill jag helt enkelt bara ta det första bästa värdet.

MEN kruxet är att värdet som plockas från den ena textkollumnen måste höra ihop med värdet som plockas från den andra textkollumnen.

LarsGMedlem sedan dec. 200012 464 inlägg
#4
select <kolumner>
  from t as q
  where textkolumn = 
    (select max(textkolumn) 
        from t
       where t.id = q.id)
TroxyMedlem sedan mars 20041 505 inlägg
#5

Nu har jag äntligen tid att visa exempel.
Antag att jag har ett resultat som ser ut såhär: (som kommer från flera JOIN)

movieId genre         genreId
------- ------------- -------
101     thriller      12
101     action        13
102     familjefilm   24
102     barnfilm      25
102     tecknat       26
103     krig          15
103     dokumentär    17
104     drama         11
104     thriller      12

Det är en sammanställning från olika butiker, så det råder lite olika uppfattningar om genre osv.
Jag vill få ut en lista över filmer, och movieId får inte förekomma fler än en gång.
Vilken genre som visas är ointressant, men det är iaf. viktigt att genre paras ihop med sitt respektive genreId.

Ovanstående resultat skulle exempelvis kunna bli:

movieId genre         genreId
------- ------------- -------
101     thriller      12
102     familjefilm   24
103     krig          15
104     drama         11

Jag tror att MySQL fixar detta automatiskt. Dvs. om man grupperar efter en viss kollumn, så plockar den resten av värdena från första bästa post.
Men SQL Server däremot gnäller och vill att jag ska gruppera alla kollumner som hämtas.

emissionMedlem sedan dec. 19996 721 inlägg
#6

Troxy skrev:

Men SQL Server däremot gnäller och vill att jag ska gruppera alla kollumner som hämtas.

Nej, den vill att du antingen grupperar eller aggregerar alla kolumner, vilket är fullständigt korrekt SQL-beteende.

Använd MIN eller MAX på de kolumner som du inte vill gruppera på.

TroxyMedlem sedan mars 20041 505 inlägg
#7

Om jag använder MAX så plockar den värden från lite olika poster, vilket den inte får.
Dvs. jag får ut värden som inte hör ihop med varandra.
I exemplet ovan så kan det hända att en genre från fel genreId.

aasahMedlem sedan mars 20034 471 inlägg
#8

Troxy skrev:

Utöver detta ID-fält, så hämtar jag även lite andra textfält som har snarlika värden, men ändå inte dubletter.

Vad är egentligen vitsen med att gruppera? Räknar du ut något per movieid, eller vill du helt enkelt visa alla filmer ihop med en genre en gång?

I det senare fallet är det bättre att inte gruppera:
Group by används för att kunna beräkna ett aggregerande värde per det du grupperar över.

Troxy skrev:

Om jag använder MAX så plockar den värden från lite olika poster, vilket den inte får.
Dvs. jag får ut värden som inte hör ihop med varandra.
I exemplet ovan så kan det hända att en genre från fel genreId.

Åh, då kan du väl lösa det med en tvåstegsraket.

CREATE VIEW temp(movieid, genreid) AS
SELECT DISTINCT movieid, MAX(genreid) FROM ...<tabeller> WHERE ...

SELECT DISTINCT T.movieid, G.genre, G.genreid FROM temp T, Genre G
WHERE G.genreid = T.genreid;

TroxyMedlem sedan mars 20041 505 inlägg
#9

aasah skrev:

vill du helt enkelt visa alla filmer ihop med en genre en gång?

Precis (y)
Så enkelt kan man förklara det :P

aasahMedlem sedan mars 20034 471 inlägg
#10

Se mitt uppdaterade svar, Troxy!

emissionMedlem sedan dec. 19996 721 inlägg
#11

aasah skrev:

Åh, då kan du väl lösa det med en tvåstegsraket.

CREATE VIEW temp(movieid, genreid) AS
SELECT DISTINCT movieid, MAX(genreid) FROM ...<tabeller> WHERE ...

SELECT DISTINCT T.movieid, G.genre, G.genreid FROM temp T, Genre G
WHERE G.genreid = T.genreid;

Aha, det var så det var tänkt! En enstegraket på samma tema fungerar också


SELECT DISTINCT T.movieid, G.genre, G.genreid FROM Genre G,
(SELECT DISTINCT movieid, MAX(genreid) AS genreid FROM ...<tabeller> WHERE ...) T
WHERE G.genreid = T.genreid;

MySQL har haft lite prestandaproblem med sådana konstruktioner (derived tables), men i SQL Server blir det bra.

TroxyMedlem sedan mars 20041 505 inlägg
#12

Tack för hjälpen.
Jag antar att jag var lite fel ute från början när jag använde GROUP BY.
Det går nog att få till en lösning av detta. :)

130 ms totalt · 3 externa anrop · v20260731065814-full.fb544a5a
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
126 ms — hämta tråd, inlägg och bilagor (db)