Avatar billede tofte Juniormester
13. juli 2010 - 22:17 Der er 10 kommentarer og
1 løsning

Problemer med GROUP

Hej

Jeg har en database med to tabeller med hver deres felter:

[kategori]
-kategori_id
-kategori_navn

[billeder]
-billede_id
-billede_tekst
-kategori_id

Hver kategori er kan indeholde mange billeder og de er linked sammen på kategori_id.

Jeg vil gerne lave et udtræk som viser alle kategorier samt et billede fra hver kategori. I mySQL kan jeg lave noget ala:
SELECT kategori_navn,billede_tekst,K.kategori,B.billede_id FROM kategori K LEFT JOIN billeder B ON K.kategori_id=B.kategori_id GROUP BY K.kategori_id

Men i MS SQL må man ikke selecte på felter man ikke grupperer eller køre en SUM på. Men jeg vil gerne have adgang til eks billede_tekst. Hvordan gøres dette nemt i MSSQL.

På Forhånd tak
Rasmus
Avatar billede arne_v Ekspert
13. juli 2010 - 22:26 #1
Man kan vist ikke lave det i nogen anden SQL dialekt end MySQL.

MySQL snupper bare en vaerdi fra en tilfaeldig raekke for de felter.

Normalt vil man have noget bestemt.

Du kan f.eks. bruge MIN eller MAX paa de kolonner du ike vil gruppere paa.
Avatar billede tofte Juniormester
13. juli 2010 - 22:40 #2
Ok, smid et svar. Jeg må stykke det sammen af flerer SELECT da jeg ikke lige kan regne ud hvordan jeg simpelt får teksten med (billede_tekst), hvis jeg eksempelvis beder den give mig den mindste id med MIN
Avatar billede arne_v Ekspert
13. juli 2010 - 23:00 #3
Ikke mindste id bare mindste billed_tekst.
Avatar billede arne_v Ekspert
13. juli 2010 - 23:01 #4
Jeg kan muligvis lave et lille eksempel senere.
Avatar billede arne_v Ekspert
13. juli 2010 - 23:01 #5
og svar
Avatar billede tofte Juniormester
13. juli 2010 - 23:01 #6
men jeg er nødt til at have den billed_tekst som hører til billede_id.
Avatar billede tofte Juniormester
13. juli 2010 - 23:13 #7
jeg er selv ude i noget lignende:
SELECT * FROM (
SELECT Min(image_id) as m_id,C.category_id as c_id FROM images I
LEFT JOIN image_category C ON I.image_category = C.category_id
GROUP BY C.category_id
) S
LEFT JOIN images I ON S.m_id=I.image_id
LEFT JOIN image_category C ON C.category_id=S.c_id

Hvilket sikkert kan gøres nemmere. Hvis du har en idé må du gerne give lyd, men jeg vil dog i seng nu.

Rasmus
Avatar billede arne_v Ekspert
14. juli 2010 - 05:04 #8
Eksempel med MIN og MAX:

mysql> CREATE TABLE b (bid INTEGER NOT NULL, aid INTEGER, btxt VARCHAR(50), PRIM
ARY KEY(bid));
Query OK, 0 rows affected (0.00 sec)

mysql>
mysql> INSERT INTO a VALUES(1,'A');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO a VALUES(2,'B');
Query OK, 1 row affected (0.00 sec)

mysql>
mysql> INSERT INTO b VALUES(1,1,'X');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO b VALUES(2,1,'Y');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO b VALUES(3,2,'Z');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO b VALUES(4,2,'W');
Query OK, 1 row affected (0.00 sec)

mysql>
mysql> SELECT a.aid,a.atxt,b.bid,b.btxt FROM a JOIN b ON a.aid=b.aid;
+-----+------+-----+------+
| aid | atxt | bid | btxt |
+-----+------+-----+------+
|  1 | A    |  1 | X    |
|  1 | A    |  2 | Y    |
|  2 | B    |  3 | Z    |
|  2 | B    |  4 | W    |
+-----+------+-----+------+
4 rows in set (0.00 sec)

mysql>
mysql> SELECT a.aid,a.atxt,b.bid,b.btxt FROM a JOIN b ON a.aid=b.aid GROUP BY a.aid;
+-----+------+-----+------+
| aid | atxt | bid | btxt |
+-----+------+-----+------+
|  1 | A    |  1 | X    |
|  2 | B    |  3 | Z    |
+-----+------+-----+------+
2 rows in set (0.00 sec)

mysql>
mysql> SELECT a.aid,MIN(a.atxt),MIN(b.bid),MIN(b.btxt) FROM a JOIN b ON a.aid=b.aid GROUP BY a.aid;
+-----+-------------+------------+-------------+
| aid | MIN(a.atxt) | MIN(b.bid) | MIN(b.btxt) |
+-----+-------------+------------+-------------+
|  1 | A          |          1 | X          |
|  2 | B          |          3 | W          |
+-----+-------------+------------+-------------+
2 rows in set (0.00 sec)

mysql>
mysql> SELECT a.aid,MAX(a.atxt),MAX(b.bid),MAX(b.btxt) FROM a JOIN b ON a.aid=b.aid GROUP BY a.aid;
+-----+-------------+------------+-------------+
| aid | MAX(a.atxt) | MAX(b.bid) | MAX(b.btxt) |
+-----+-------------+------------+-------------+
|  1 | A          |          2 | Y          |
|  2 | B          |          4 | Z          |
+-----+-------------+------------+-------------+
2 rows in set (0.00 sec)

mysql>
mysql> DROP TABLE a;
Query OK, 0 rows affected (0.01 sec)

mysql> DROP TABLE b;
Query OK, 0 rows affected (0.00 sec)
Avatar billede arne_v Ekspert
14. juli 2010 - 05:06 #9
Der er en lille forskel mellem brug af MIN/MAX og en inner select.

En inner select vil altid hente kolonne værdier fra samme række - det vil MIN/MAX ikke.
Avatar billede tofte Juniormester
14. juli 2010 - 09:13 #10
tak for dit eksempel. Jeg skal bruge kolonnerne fra samme række, men jeg kan eks bruge min(a.atxt) til at hente denne tekst da der bliver grupperet på a.id og så laver en inner select på række b for at få en tilhørende tekst og værdi.
Avatar billede HenrikSjang Nybegynder
14. juli 2010 - 13:04 #11
Denne problematik er en af dem der nemt kan løses med en cte og brug af row_number() funktionen:

;with CTE
as (
select
    ROW_NUMBER() OVER(PARTITION BY k.kategori_id ORDER BY b.billed_id) as rn,
    kategori_navn,
    billede_tekst ,
    k.kategori_id,
    b.billede_id
from Kategori k
left outer join billeder b on k.kategori_id = b.kategori_id
)
select * from CTE
where rn = 1
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester