webForumDet fria alternativet

visa tillhörande kategorier, join table osv

Databaser & SQL

6 svar · 644 visningar · startad av Freppa

Medlem sedan maj 20057 inlägg
Frågan#1

Är lite osäker på om det här hör hemma här men någon får väl flytta det om så skulle vara fallet.

Jag har tre tabeller som ser ut ungefär såhär lite förenklat

produkter
p_id|p_name

1|produkt1
2|produkt2
3|produkt3

kategorier
k_id|k_name

1|kat1
2|kat2
3|kat3

koppling
p_id|k_id

1|1
1|3
2|3
3|1
3|2
3|3

Då använder jag ju följande för att ta fram alla produkter som till hör kategori 1:

SELECT * FROM produkter JOIN koppling ON produkter.p_id = koppling.p_id where koppling.k_id = 1

Resultatet hamnar i en array som jag sen kan loopa igenom och visa som jag vill i en tabell. tex

produkt1|pris|mm
produkt3|pris|mm

Det jag även vill göra är att skriva ut vilka kategorier (hela kategorinamnen) som tillhör produkten

produkt1|pris|mm|kat1, kat3
produkt3|pris|mm|kat1, kat2, kat3

Måste jag utföra ett nytt anrop mot databasen samtidigt som loopen ska skriva ut den övriga informationen om produkten eller kan detta göra på något annat smidigt sätt?
Känns dumt att behöva anropa databasen 25 extra ggr bara för att lista 25 prudukter.

Hoppas nu att jag lyckats vara tillräckligt tydlig med vad jag vill göra.

Medlem sedan dec. 20014 239 inlägg
#2

Flyttas från PHP

Medlem sedan dec. 20025 483 inlägg
#3

Red./ Fel

Medlem sedan dec. 200012 464 inlägg
#4
select p_namn as produktnamn,
       pris,
       k_namn as kategori
  from produkter 
  join koppling
    on koppling.p_id = produkter.p_id
  join kategori 
    on koppling.k_id = kategori.k_id
 where p_id in 
       (select p_id
          from koppling
         where koppling.k_id = 1)
 order by produkter.p_id

sen så får du själv hålla reda på när det kommer en ny produkt.

Medlem sedan maj 20057 inlägg
#5

LarsG skrev:

select p_namn as produktnamn,
       pris,
       k_namn as kategori
  from produkter 
  join koppling
    on koppling.p_id = produkter.p_id
  join kategori 
    on koppling.k_id = kategori.k_id
 where p_id in 
       (select p_id
          from koppling
         where koppling.k_id = 1)
 order by produkter.p_id

sen så får du själv hålla reda på när det kommer en ny produkt.

Använder jag det som du skriver LarsG så får jag ju ut flera rader med samma produkter (en ny rad med dublett av produkten för varje kategori).
Jag vill endast få produkten en gång och sen lista tillhörande kategorier.

Är det jag som missar något kanske?

Dessutom verkar det ta väääldigt lång tid att köra den sql-frågan (har bara kört den i phpmyadmin), ca 10 sek för att få fram resultatet.
tabellen produkter innehåller ca 1500 rader, kategorier 24 rader och kopplingstabellen lite drygt 3200 rader..
Har jag väl kört frågan en gång går det väldigt fort att köra den igen tills jag byter kategori, då tar det ytterligare 10 sek att få fram något resultat.

Medlem sedan aug. 20039 340 inlägg
#6

Kolla in GROUP_CONCAT. Fritt utifrån LarsG's fråga:

select p_namn as produktnamn,
       pris,
       GROUP_CONCAT(DISTINCT k_namn SEPARATOR ',') as kategorier
  from produkter 
  join koppling
    on koppling.p_id = produkter.p_id
  join kategori 
    on koppling.k_id = kategori.k_id
 where p_id in 
       (select p_id
          from koppling
         where koppling.k_id = 1)
 group by produkter.p_id
 order by produkter.p_id

Notera för övrigt följande i dokumentationen:

The result is truncated to the maximum length that is given by the group_concat_max_len system variable, which has a default value of 1024. The value can be set higher, although the effective maximum length of the return value is constrained by the value of max_allowed_packet. The syntax to change the value of group_concat_max_len at runtime is as follows, where val is an unsigned integer:
SET [GLOBAL | SESSION] group_concat_max_len = val;

Vad gäller långsamthet låter som om du behöver indexera dina tabeller. Gå in i structure för tabellen i phpmyadmin. Där kan du välja tre typer av indexering (längst till höger under action), primär (Nyckel-symbol), unik (Ett U), eller vanlig, icke-unik (En blixt). I koppling bör du indexera båda kolumnera med vanlig indexering. I produkter och kategorier bör du indexera vardera id som unik, eller kanske till och med primär. (Beroende på vilken funktion id't har) När det har fått tugga ett par mnuter på servern ska du se att allt går mycket fortare.

Medlem sedan maj 20057 inlägg
#7

Det där gjorde susen! Tack!

Angående hastigheten så hade jag redan dessa kolumner indexerade så jag började trimma till alla kolumntyper som fortfarande var lite provisoriska vilket kapade ner tiden rejält. :)

257 ms totalt · 4 externa anrop · v20260731065814-full.86ec41c2
125 ms — deklarationer (db)
0 ms — hämta statistik (cache)
128 ms — hämta tråd, inlägg och bilagor (db)
122 ms — ändringar (db)