Gå til innhold

MySQL: concat(rader fra tabell)


Anbefalte innlegg

Dette blir mye mysql, lite php, men i mangel av noe sql forum er det vel leserene av php forumet som kan mest mysql, så jeg prøver meg her.

 

Jeg ønsker et alternativ (helst et mysql query) til en php loop som utfører vanvittig mange query, som blir veldig inneffektivt ved større datamengder, spessielt om mysql serveren og webserveren ikke er samme maskin. En eksempel database ser slik ut:

 

tabell2:

id tekst

1 a

1 b

2 a

3 b

1 c

3 d

2 b

 

tabell1:

navn fremmedId

aaa 3

bbb 1

ccc 2

ddd 4

 

Resultatet av query skulle da sett slik ut:

navn tekst

aaa b,d

bbb a,b,c

ccc a,b

ddd

 

PHP koden som gjør jobben er:

$i=0;

$tab1=mysql_query("SELECT id, navn, fremmedId FROM tabell1");

while($row = mysql_fetch_array($tab1)) {

$navn[$i]=$row[navn];

$tab2=mysql_query("SELECT tekst FROM tabell2 WHERE id=$row[fremmedId]");

while($temp=mysql_fetch_array($tab2)) {

if(empty($tekst[$i])) { $tekst[$i]=$temp[tekst]; }

else { $tekst[$i].=",".$temp[tekst]; }

}

$i++;

}

 

 

Søker et query som gjør det denne kunne ha gjort hvis den hadde fungert:

SELECT tabell1.navn, concate_ws(",",tabell2.tekst) as tekst FROM tabell1, tabell2 WHERE tabell1.fremmedId = tabell2.id;

 

Spørsmålet altså hvordan lage et slikt query, som faktisk virker?

 

En måte kunne vært å bruke temporary tables, men det stopper fortsatt ved at man trenger et slikt query:

INSERT INTO temp SELECT concate_ws(",",tekst) FROM tabell2;

 

Takker for alle forslag

 

-pg

Lenke til kommentar
Videoannonse
Annonse

Det virker som funksjonen du leter etter er JOIN.

Du trenger to like felt i begge tabellene, f.eks. id i en tabell må være lik en verdi i en annen tabell.

 

Siden du har en hovedtabell og skal hente tilhørene verdi fra en annen tabell (der id i hovedtabellen = et felt i den andre tabellen), kan du bruke join metoden LEFT JOIN.

 

Hvilke felter vil du hente fra tabellene?

Skal du telle antallet verdier?

 

aaa 3 bbb 1 ccc 2 ddd 4 a b c d - gjør det litt vansklig å forstå. I steden for å eksemplifisere på den måten fortell heler hvilke felter som er i tabellene, hvilke felter som er like i tabellen og hvilke felter du vil hente ut.

 

Her er et eksempel på en LEFT JOIN query. Du kan bygge viderer på den, eller poste litt "bedre" om hva du vil hente så kan vi hjelpe deg å sette opp query'en.

 

SELECT tb1.navn, concate_ws(",",tb2.tekst) as tekst FROM tabell1 AS tb1 LEFT JOIN tabell2 AS tb2 ON tb1.fremmedId = tb2.id;

Lenke til kommentar

JOIN funker ikke på den måten.

Akke's forslag er det samme som vanlig JOIN, mens LEFT JOIN vil også ta med det at tbl1 som ikke har noen referanse i tbl2.

 

Problemet mitt ligger i at jeg vil ha en resultat tabell hvor en kolonne består av teksten fra alle matchende rader i tabellen som "joines".

 

Med (LEFT) JOIN ville resultat tabellen sett slik ut:

aaa b

aaa d

bbb a

bbb b

bbb c

ccc a

ccc b

ddd <-vil kun komme ved LEFT JOIN

 

Så, hvis man kunne brukt concat() i kombinasjon med GROUP BY navn ville det vært mulig å få den ønskede tabellen:

aaa b,d

bbb a,b,c

ccc a,b

ddd

Lenke til kommentar

Okay, du vil ha alle feltene listet opp etter group by.

Det er ikke noe problem dersom du har MySQL 4.1 eller høyere, ta en kikk på:

http://www.mysql.com/doc/en/GROUP-BY-Functions.html

Men siden den versjonene ikke er stabil(eller ferdig) ennå er det ikke mange som bruker den. (Du må fortsatt joine tabellene)

 

Det er likevel mulig å fikse det med PHP uten å kjøre mange spørringer. Du klarer der med en spørring dersom du bruker JOIN. Hent ut all dataen med en vanlig join, slik at resultatet blir:

aaa x

aaa y

bbb x

bbb z

 

Så lager du en funksjon som leser dataen inn en array.

 

f.eks.

 

while($rad = mysql_fetch_array($result)){

$array[$rad['navn']][] = $rad['verdi'];

}

 

Da ligger alle verdiene til f.eks. aaa i array'en $array['aaa'].

 

Hvis du ikke vil at feltene skal ligge i varaiabler som $array['aaa'][1] og $array['aaa'][2], men vil heller at alt skal leses inn i f.eks. $array['aaa'] bruker du bare .=

 

f.eks.

 

while($rad = mysql_fetch_array($result)){

$array[$rad['navn']] .= $rad['verdi'];

}

Lenke til kommentar

For å kunne restarte mysql (helst også serveren) kan du bruke exec() funksjonene som starter et program du laster ned (eller lager) som restarter serveren.

 

MySQL 4.1 er alpha release - dvs. det gjenstår sikkert mange reprasjoner av bugs - MySQL er mest ment for at programmerere skal kunne teste nye funksjoner. Grunnen til at du ikke har hørt for mye om stabiliteten til mysql 5 kan være fordi det er ikke mange som bruker den på full tid ennå.

 

Det beste er å holde seg til stabile versjoner, men versjon 4.1 kan til nød gå. Det er mye jobb å ta back-up hver dag og eventuelt måtte legge de inn igjen dersom du må reinstallere mysql.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...