sql >> Databáze >  >> RDS >> Mysql

Lze to provést v dotazu MySQL, nebo je to nutné provést v PHP? (strana serveru)

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ů).




  1. Chybějící výsledek v povinných polích

  2. Jak se připojit k MySQL s X509 pomocí JDBC?

  3. Jak rozdělit řetězec a vložit hodnoty do tabulky v SQL Server

  4. Jak najít duplicitní záznamy v MySQL