Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Kann dies in einer MySQL-Abfrage durchgeführt werden, oder muss es in PHP erfolgen? (serverseitig)

Dies kann in sql erfolgen . Eine Möglichkeit wäre, eine "Hilfstabelle" mit nur Ganzzahlen zu verwenden, die Sie join können Ihre Daten gegen, um Ihre Zeile mehrmals zu erhalten und dann nur das n zu extrahieren -tes Unterelement.

Versuchen Sie Folgendes:

-- 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;

Das ergibt:

+---------------+----+-----------------+
| 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  |                 |
+---------------+----+-----------------+

Ich habe Ihre Beispieldaten verwendet, denen einige , fehlen , weshalb das Ergebnis z.B. March 2 Feb 27 . Beachten Sie auch, dass einige Untereinträge leer sind (da meine Beispieldaten leere Einträge enthalten); Sie können sie herausfiltern oder nicht. Ihre Integer-Tabelle muss natürlich Zahlen mindestens bis zur maximalen Anzahl von Elementen enthalten, die Sie in einer Ihrer Zeilen erwarten (und wenn sie eine 0 enthält oder negative Zahlen, filtern Sie diese im on heraus -Klausel).

substring_index(str,delim,count) gibt den Teilstring von String str zurück vor count Vorkommen des Trennzeichens delim . Die vollständige Anweisung für subentry gibt für eine positive Zahl entweder die _int_1_10.id zurück -tes Element oder, wenn die Zeichenfolge weniger Elemente hat, das letzte Element.

Der on -Klausel berechnet somit die Anzahl der Elemente (durch Zählen der Anzahl von , ), um zu verhindern, dass das letzte Element mehrmals abgerufen wird. Wenn Ihr String keine leeren Elemente enthält (wie die ,, in meinen Beispieldaten), brauchen Sie diesen Teil nicht, könnten aber ein leeres Element hinzufügen, um das Ende der Liste zu markieren.

Sie können diesen Code auf Ihre gesamte Ergebnismenge anwenden, z. durch Verwendung von

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

Es wird funktionieren, aber es könnte langsam sein. Es kann keinen Index für space*_2_value verwenden -Spalten und müssen viel Joining und String-Evaluation durchführen. Sie können jedoch nicht viel dagegen tun, außer Ihre Daten zu normalisieren.

Wenn es sinnvoll ist, dies in sql zu tun wird wahrscheinlich davon abhängen, was Sie mit den Daten tun. Wenn Sie es nur in einer HTML-Tabelle auf einer Webseite anzeigen möchten, ist es möglicherweise einfacher und schneller, das Array in php einfach zu durchlaufen . Zum Sortieren, Filtern oder join Ihre Ergebnismenge, es ist wahrscheinlich viel einfacher (und wahrscheinlich schneller) in sql zu implementieren , vielleicht sogar, wenn Sie es in einem Framework verwenden. Wenn Sie die Werte aktualisieren, ist dies viel einfacher in php , da es höchstwahrscheinlich ein Durcheinander in sql geben wird (auf dieser Ergebnismenge).