Hướng dẫn mysql split string multiple rows - mysql tách chuỗi nhiều hàng

Nếu bạn có thể tạo bảng số, chứa các số từ 1 đến các trường tối đa để phân chia, bạn có thể sử dụng một giải pháp như thế này:

select
  tablename.id,
  SUBSTRING_INDEX[SUBSTRING_INDEX[tablename.name, ',', numbers.n], ',', -1] name
from
  numbers inner join tablename
  on CHAR_LENGTH[tablename.name]
     -CHAR_LENGTH[REPLACE[tablename.name, ',', '']]>=numbers.n-1
order by
  id, n

Vui lòng xem Fiddle tại đây.

Nếu bạn không thể tạo bảng, thì một giải pháp có thể là:

select
  tablename.id,
  SUBSTRING_INDEX[SUBSTRING_INDEX[tablename.name, ',', numbers.n], ',', -1] name
from
  [select 1 n union all
   select 2 union all select 3 union all
   select 4 union all select 5] numbers INNER JOIN tablename
  on CHAR_LENGTH[tablename.name]
     -CHAR_LENGTH[REPLACE[tablename.name, ',', '']]>=numbers.n-1
order by
  id, n

Một ví dụ fiddle là ở đây.

Đã trả lời ngày 30 tháng 7 năm 2013 lúc 9:05Jul 30, 2013 at 9:05

fthiellafthiellafthiella

47.2K15 Huy hiệu vàng90 Huy hiệu bạc104 Huy hiệu đồng15 gold badges90 silver badges104 bronze badges

9

Nếu cột

select t.id, j.name
from mytable t
join json_table[
  t.name,
  '$[*]' columns [name varchar[50] path '$']
] j;
1 là mảng JSON [như
select t.id, j.name
from mytable t
join json_table[
  t.name,
  '$[*]' columns [name varchar[50] path '$']
] j;
2], thì bạn có thể trích xuất/giải nén nó bằng json_table [] [có sẵn kể từ MySQL 8.0.4]:

select t.id, j.name
from mytable t
join json_table[
  t.name,
  '$[*]' columns [name varchar[50] path '$']
] j;

Result:

| id  | name |
| --- | ---- |
| 1   | a    |
| 1   | b    |
| 1   | c    |
| 2   | b    |

Xem trên DB Fiddle

Nếu bạn lưu trữ các giá trị ở định dạng CSV đơn giản, thì trước tiên bạn sẽ cần chuyển đổi nó thành JSON:

select t.id, j.name
from mytable t
join json_table[
  replace[json_array[t.name], ',', '","'],
  '$[*]' columns [name varchar[50] path '$']
] j

Result:

| id  | name |
| --- | ---- |
| 1   | a    |
| 1   | b    |
| 1   | c    |
| 2   | b    |

Xem trên DB Fiddle

Nếu bạn lưu trữ các giá trị ở định dạng CSV đơn giản, thì trước tiên bạn sẽ cần chuyển đổi nó thành JSON:Dec 6, 2019 at 10:10

Đã trả lời ngày 6 tháng 12 năm 2019 lúc 10:10Paul Spiegel

Paul Spiegelpaul Spiegel5 gold badges43 silver badges53 bronze badges

4

30.3k5 Huy hiệu vàng43 Huy hiệu bạc53 Huy hiệu Đồng

DELIMITER $$

CREATE FUNCTION strSplit[x VARCHAR[65000], delim VARCHAR[12], pos INTEGER] 
RETURNS VARCHAR[65000]
BEGIN
  DECLARE output VARCHAR[65000];
  SET output = REPLACE[SUBSTRING[SUBSTRING_INDEX[x, delim, pos]
                 , LENGTH[SUBSTRING_INDEX[x, delim, pos - 1]] + 1]
                 , delim
                 , ''];
  IF output = '' THEN SET output = null; END IF;
  RETURN output;
END $$


CREATE PROCEDURE BadTableToGoodTable[]
BEGIN
  DECLARE i INTEGER;

  SET i = 1;
  REPEAT
    INSERT INTO GoodTable [id, name]
      SELECT id, strSplit[name, ',', i] FROM BadTable
      WHERE strSplit[name, ',', i] IS NOT NULL;
    SET i = i + 1;
    UNTIL ROW_COUNT[] = 0
  END REPEAT;
END $$

DELIMITER ;

Đã trả lời ngày 30 tháng 7 năm 2013 lúc 9:05Jul 30, 2013 at 9:05

fthiellafthiellaPrahalad Gaggar

47.2K15 Huy hiệu vàng90 Huy hiệu bạc104 Huy hiệu đồng16 gold badges51 silver badges70 bronze badges

0

Nếu cột

select t.id, j.name
from mytable t
join json_table[
  t.name,
  '$[*]' columns [name varchar[50] path '$']
] j;
1 là mảng JSON [như
select t.id, j.name
from mytable t
join json_table[
  t.name,
  '$[*]' columns [name varchar[50] path '$']
] j;
2], thì bạn có thể trích xuất/giải nén nó bằng json_table [] [có sẵn kể từ MySQL 8.0.4]:

with recursive
    T as [ select 'a,b,c,d,e,f' as items],
    N as [ select 1 as n union select n + 1 from N, T
        where n =numbers.n-1
order by
  id, n
1

Biến thể của tôi: Quy trình được lưu trữ lấy tên bảng, tên trường và dấu phân cách làm đối số. Lấy cảm hứng từ bài đăng //www.marcogoncalves.com/2011/03/mysql-split-column-string-into-lows/Jul 5 at 10:14

select
  tablename.id,
  SUBSTRING_INDEX[SUBSTRING_INDEX[tablename.name, ',', numbers.n], ',', -1] name
from
  [select 1 n union all
   select 2 union all select 3 union all
   select 4 union all select 5] numbers INNER JOIN tablename
  on CHAR_LENGTH[tablename.name]
     -CHAR_LENGTH[REPLACE[tablename.name, ',', '']]>=numbers.n-1
order by
  id, n
2

Ví dụ sử dụng [bình thường hóa]:Oct 15, 2016 at 8:26

AshkufarazImanez

5.1446 Huy hiệu vàng49 Huy hiệu bạc81 Huy hiệu đồng5 silver badges13 bronze badges

Đã trả lời ngày 5 tháng 2 năm 2017 lúc 12:57

Andreyandrey

1.42517 Huy hiệu bạc13 Huy hiệu đồng

Bởi vì bạn phải tiếp tục thêm "Chọn số liên minh" trong ví dụ trên có thể là một vấn đề nếu bạn cần một số lượng lớn các lần chia tách.

select
  tablename.id,
  SUBSTRING_INDEX[SUBSTRING_INDEX[tablename.name, ',', numbers.n], ',', -1] name
from
  [select 1 n union all
   select 2 union all select 3 union all
   select 4 union all select 5] numbers INNER JOIN tablename
  on CHAR_LENGTH[tablename.name]
     -CHAR_LENGTH[REPLACE[tablename.name, ',', '']]>=numbers.n-1
order by
  id, n
3

Tôi đã quyết định một cách tốt hơn là điều này chỉ thêm một hàng số cho mỗi chữ số. Ví dụ dưới đây là tốt cho 1-1000 Thêm một hàng khác làm cho nó tốt cho 1-10000, v.v.May 29, 2019 at 20:11

2

Đã trả lời ngày 5 tháng 7 lúc 10:14

select
  tablename.id,
  SUBSTRING_INDEX[SUBSTRING_INDEX[tablename.name, ',', numbers.n], ',', -1] name
from
  [select 1 n union all
   select 2 union all select 3 union all
   select 4 union all select 5] numbers INNER JOIN tablename
  on CHAR_LENGTH[tablename.name]
     -CHAR_LENGTH[REPLACE[tablename.name, ',', '']]>=numbers.n-1
order by
  id, n
4

Đã trả lời ngày 15 tháng 10 năm 2016 lúc 8:26

select
  tablename.id,
  SUBSTRING_INDEX[SUBSTRING_INDEX[tablename.name, ',', numbers.n], ',', -1] name
from
  [select 1 n union all
   select 2 union all select 3 union all
   select 4 union all select 5] numbers INNER JOIN tablename
  on CHAR_LENGTH[tablename.name]
     -CHAR_LENGTH[REPLACE[tablename.name, ',', '']]>=numbers.n-1
order by
  id, n
5
select
  tablename.id,
  SUBSTRING_INDEX[SUBSTRING_INDEX[tablename.name, ',', numbers.n], ',', -1] name
from
  [select 1 n union all
   select 2 union all select 3 union all
   select 4 union all select 5] numbers INNER JOIN tablename
  on CHAR_LENGTH[tablename.name]
     -CHAR_LENGTH[REPLACE[tablename.name, ',', '']]>=numbers.n-1
order by
  id, n
6

Imanezimanez

select
  tablename.id,
  SUBSTRING_INDEX[SUBSTRING_INDEX[tablename.name, ',', numbers.n], ',', -1] name
from
  [select 1 n union all
   select 2 union all select 3 union all
   select 4 union all select 5] numbers INNER JOIN tablename
  on CHAR_LENGTH[tablename.name]
     -CHAR_LENGTH[REPLACE[tablename.name, ',', '']]>=numbers.n-1
order by
  id, n
7
select
  tablename.id,
  SUBSTRING_INDEX[SUBSTRING_INDEX[tablename.name, ',', numbers.n], ',', -1] name
from
  [select 1 n union all
   select 2 union all select 3 union all
   select 4 union all select 5] numbers INNER JOIN tablename
  on CHAR_LENGTH[tablename.name]
     -CHAR_LENGTH[REPLACE[tablename.name, ',', '']]>=numbers.n-1
order by
  id, n
8

5005 huy hiệu bạc13 huy hiệu đồngAug 18, 2020 at 7:00

Câu hỏi ban đầu là cho MySQL và SQL nói chung. Ví dụ dưới đây là cho các phiên bản mới của MySQL. Thật không may, một truy vấn chung sẽ hoạt động trên bất kỳ máy chủ SQL nào là không thể. Một số máy chủ không hỗ trợ CTE, các máy chủ khác không có Subring_index, nhưng các máy chủ khác có chức năng tích hợp để chia chuỗi thành nhiều hàng.

select
  tablename.id,
  SUBSTRING_INDEX[SUBSTRING_INDEX[tablename.name, ',', numbers.n], ',', -1] name
from
  [select 1 n union all
   select 2 union all select 3 union all
   select 4 union all select 5] numbers INNER JOIN tablename
  on CHAR_LENGTH[tablename.name]
     -CHAR_LENGTH[REPLACE[tablename.name, ',', '']]>=numbers.n-1
order by
  id, n
9

--- câu trả lời sau ---Nov 14, 2018 at 20:25

1

select t.id, j.name
from mytable t
join json_table[
  t.name,
  '$[*]' columns [name varchar[50] path '$']
] j;
0

Các truy vấn đệ quy thuận tiện khi máy chủ không cung cấp chức năng tích hợp. Họ cũng có thể là nút cổ chai.

Truy vấn sau đây đã được viết và kiểm tra trên MySQL phiên bản 8.0.16. Nó sẽ không hoạt động trên phiên bản 5.7-. Các phiên bản cũ không hỗ trợ biểu thức bảng chung [CTE] và do đó truy vấn đệ quy.Aug 19, 2021 at 18:46

1

Làm thế nào chia một chuỗi thành nhiều hàng trong SQL?

Hàm String_Split [] là hàm có giá trị bảng chia chuỗi thành một bảng bao gồm các hàng của các chuỗi nền dựa trên một dấu phân cách được chỉ định. Trong cú pháp này: Input_String là một biểu thức dựa trên ký tự đánh giá thành một chuỗi nvarchar, varchar, nchar hoặc char. is a table-valued function that splits a string into a table that consists of rows of substrings based on a specified separator. In this syntax: input_string is a character-based expression that evaluates to a string of NVARCHAR , VARCHAR , NCHAR , or CHAR .

Làm thế nào tôi có thể nhận được nhiều dữ liệu hàng trong chuỗi phân tách bằng dấu phẩy trong SQL?

Câu trả lời của bạn..
Dữ liệu kiểm tra khai báo @Bảng1 Bảng [ID int, giá trị int] chèn vào các giá trị @Bảng1 [1.100], [1.200], [1.300], [1.400].
Truy vấn chọn id, công cụ [[chọn ',' + cast [value as varchar [10]] [text []] từ @Bảng1 trong đó id = t.id cho đường dẫn xml [''], loại] .value ['.','.

Bạn có thể chia một chuỗi trong SQL không?

Chức năng String_Split [String, Delector] trong SQL Server chia chuỗi vào đối số đầu tiên bằng dấu phân cách trong đối số thứ hai.Để chia một câu thành các từ, hãy chỉ định câu là đối số đầu tiên của hàm String_Split [] và '' là đối số thứ hai.. To split a sentence into words, specify the sentence as the first argument of the STRING_SPLIT[] function and ' ' as the second argument.

Tôi có thể nối nhiều hàng mysql vào một trường không?

Hàm group_concat [] trong mysql được sử dụng để kết hợp dữ liệu từ nhiều hàng vào một trường.Đây là hàm tổng hợp [nhóm theo] trả về giá trị chuỗi, nếu nhóm chứa ít nhất một giá trị không null.. This is an aggregate [GROUP BY] function which returns a String value, if the group contains at least one non-NULL value.

Bài Viết Liên Quan

Chủ Đề