sql >> Database teknologi >  >> RDS >> Mysql

Kan dette gøres i en MySQL-forespørgsel, eller skal det gøres i PHP? (serverside)

Dette kan gøres i sql . En måde ville være at bruge en "hjælpetabel" med kun heltal, som du kan join dine data mod for at få din række flere gange og derefter for kun at udtrække n -th underelement.

Prøv dette:

-- helper table with a listof integers from 1 to 10 create table _int_1_10 (id int primary key); insert into _int_1_10 (id) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); -- some example data create table test_strexplode ( id int primary key, space_value_1 varchar(200), space_value_2 varchar(200) ); insert into test_strexplode (id, space_value_1, space_value_2) values (1, 'row 1', 'March 3,March 5,March 6 March 1,March 2 Feb 27'), (2, 'row 2', 'March 3,,March 5'), (3, 'row 3', ''); select space_value_1, _int_1_10.id, -- extracts the "_int_1_10.id"th element SUBSTRING_INDEX(SUBSTRING_INDEX( space_value_2,',',_int_1_10.id),',',-1) as subentry from test_strexplode join _int_1_10 on _int_1_10.id <= -- number of elements in your string (= number of "," + 1) char_length(space_value_2) - char_length(replace(space_value_2, ',', '')) + 1 order by test_strexplode.id, _int_1_10.id;

Dette vil give dig:

+---------------+----+-----------------+ | space_value_1 | id | subentry | +---------------+----+-----------------+ | row 1 | 1 | March 3 | | row 1 | 2 | March 5 | | row 1 | 3 | March 6 March 1 | | row 1 | 4 | March 2 Feb 27 | | row 2 | 1 | March 3 | | row 2 | 2 | | | row 2 | 3 | March 5 | | row 3 | 1 | | +---------------+----+-----------------+

Jeg brugte dine eksempeldata, der mangler nogle , , hvorfor resultatet indeholder bl.a. March 2 Feb 27 . Bemærk også, at nogle underposter er tomme (da mine eksempeldata inkluderer tomme poster); du vil måske ikke filtrere dem fra. Din heltalstabel skal naturligvis indeholde tal mindst op til det maksimale antal elementer, du forventer at have i nogen af ​​dine rækker (og hvis den indeholder en 0 eller negative tal, filtrer dem fra i on -klausul).

substring_index(str,delim,count) returnerer understrengen fra strengen str før count forekomster af afgrænsningstegnet delim . Den fulde erklæring for subentry vil, for et positivt tal, returnere enten _int_1_10.id -th element eller, hvis strengen har færre elementer, det sidste element.

on -clausul beregner således antallet af elementer (ved at tælle antallet af , ) for at undgå at få det sidste element flere gange. Hvis din streng ikke indeholder tomme elementer (såsom ,, i mine eksempeldata), behøver du ikke den del, men du kan tilføje et tomt element for at markere slutningen af ​​listen.

Du kan anvende denne kode på hele dit resultatsæt, f.eks. ved at bruge

...
from (select ... 
         space1_1_value as space_value_1,
         space1_2_value as space_value_2
      ...
      union all ... union all ... ) as test_strexplode 
join _int_1_10 ...
 

Det vil virke, men det kan være langsomt. Den kan ikke bruge et indeks på space*_2_value -kolonner og skal lave en masse sammenføjning og strengevaluering. Du kan dog ikke gøre meget ved det, bortset fra at normalisere dine data.

Hvis det er nyttigt at gøre dette i sql vil sandsynligvis afhænge af, hvad du laver med dataene. Hvis du bare skal vise det i en html-tabel på en webside, kan det være både nemmere og hurtigere blot at gå gennem arrayet i php . For at sortere, filtrere eller join dit resultatsæt, er det sandsynligvis meget nemmere at implementere (og sandsynligvis hurtigere) i sql , måske endda hvis du bruger det i en ramme. Hvis du skal opdatere værdierne, vil det være meget nemmere at gøre i php , da det højst sandsynligt bliver noget rod i sql (på dette resultatsæt).




  1. Hvad er forskellene mellem SQL og MySQL

  2. Informationsskema og primære nøgler

  3. mysql-struktur til indlæg og kommentarer

  4. Langsomt kørende Postgres-forespørgsel