To lze provést v sql . Jedním ze způsobů by bylo použití "pomocné tabulky" pouze s celými čísly, ke kterým se můžete join
vaše data proti, abyste svůj řádek získali několikrát a poté extrahovali pouze n
-tý dílčí prvek.
Zkuste toto:
-- 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;
Tím získáte:
+---------------+----+-----------------+
| 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 | |
+---------------+----+-----------------+
Použil jsem vaše ukázková data, ve kterých chybí nějaké ,
, proto výsledek obsahuje např. March 2 Feb 27
. Všimněte si také, že některé podpoložky jsou prázdné (protože moje ukázková data obsahují prázdné položky); můžete nebo nemusíte chtít je odfiltrovat. Vaše celočíselná tabulka bude zjevně muset obsahovat čísla alespoň do maximálního počtu prvků, které očekáváte v kterémkoli z vašich řádků (a pokud obsahuje 0
nebo záporná čísla, odfiltrujte je v on
-klauzule).
substring_index(str,delim,count)
vrátí podřetězec z řetězce str
před count
výskyty oddělovače delim
. Úplný výpis pro subentry
pro kladné číslo vrátí buď _int_1_10.id
-tý prvek nebo, pokud má řetězec méně prvků, poslední prvek.
on
-klauzule tedy vypočítá počet prvků (počítáním počtu ,
), abyste zabránili opakovanému získání posledního prvku. Pokud váš řetězec neobsahuje žádné prázdné prvky (jako ,,
v mých ukázkových datech), tuto část nepotřebujete, ale můžete přidat prázdný prvek pro označení konce seznamu.
Tento kód můžete použít na celou sadu výsledků, např. pomocí
...
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 ...
Bude to fungovat, ale může to být pomalé. Nemůže použít index na space*_2_value
-sloupce a bude muset udělat spoustu spojování a vyhodnocování řetězců. S tím však nemůžete mnoho udělat, kromě normalizace vašich dat.
Pokud je užitečné to udělat v sql bude pravděpodobně záviset na tom, co s daty děláte. Pokud jej chcete zobrazit v html tabulce na webové stránce, může být jednodušší a rychlejší procházet pole v php . Chcete-li třídit, filtrovat nebo join
vaší sady výsledků, je pravděpodobně mnohem jednodušší (a pravděpodobně rychlejší) implementovat v sql , možná i když jej používáte v rámci. Pokud se chystáte aktualizovat hodnoty, bude to mnohem jednodušší v php , protože to s největší pravděpodobností bude nepořádek v sql (na této sadě výsledků).