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
1Biế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
2Ví 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
3Tô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
5select
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
6Imanezimanez
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
7select
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
85005 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;
0Cá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