Dit kan in sql . Een manier zou zijn om een "helpertabel" te gebruiken met alleen gehele getallen waaraan u kunt join
uw gegevens tegen om uw rij meerdere keren te krijgen en vervolgens om alleen de n
. te extraheren -de subelement.
Probeer dit:
-- 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;
Dit geeft je:
+---------------+----+-----------------+
| 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 | |
+---------------+----+-----------------+
Ik heb je voorbeeldgegevens gebruikt die enkele ,
, daarom bevat het resultaat b.v. March 2 Feb 27
. Merk ook op dat sommige subitems leeg zijn (omdat mijn voorbeeldgegevens lege items bevatten); misschien wilt u ze er wel of niet uit filteren. Uw integer-tabel moet uiteraard getallen bevatten tot het maximum aantal elementen dat u verwacht in een van uw rijen te hebben (en als deze een 0
bevat of negatieve getallen, filter ze uit in de on
-clausule).
substring_index(str,delim,count)
geeft de subtekenreeks terug van tekenreeks str
voor count
voorkomens van het scheidingsteken delim
. De volledige instructie voor subentry
zal, voor een positief getal, ofwel de _int_1_10.id
. retourneren -th element of, als de string minder elementen heeft, het laatste element.
De on
-clause berekent dus het aantal elementen (door het aantal ,
) om te voorkomen dat u het laatste element meerdere keren krijgt. Als je string geen lege elementen bevat (zoals de ,,
in mijn voorbeeldgegevens), hebt u dat deel niet nodig, maar kunt u een leeg element toevoegen om het einde van de lijst te markeren.
U kunt deze code toepassen op uw hele resultatenset, b.v. met behulp van
...
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 ...
Het zal werken, maar het kan traag zijn. Het kan geen index gebruiken op de space*_2_value
-kolommen en zal veel voegwerk en string-evaluatie moeten doen. U kunt er echter niet veel aan doen, behalve uw gegevens normaliseren.
Als het handig is om dit te doen in sql hangt waarschijnlijk af van wat u met de gegevens doet. Als je het gewoon in een html-tabel op een webpagina wilt weergeven, kan het zowel gemakkelijker als sneller zijn om gewoon door de array in php te bladeren . Sorteren, filteren of join
uw resultatenset, is het waarschijnlijk veel gemakkelijker te implementeren (en waarschijnlijk sneller) in sql , misschien zelfs als u het in een raamwerk gebruikt. Als je de waarden gaat bijwerken, zal het veel gemakkelijker zijn om dit te doen in php , aangezien het hoogstwaarschijnlijk een puinhoop wordt in sql (op deze resultatenset).