MySQL - 如何select 一个列以便结果是一个树结构?

MySQL - How to select a column so that the outcome be a tree structure?

如果我有一个带有以下快照的给定列

"A - B - 1"
"A - B - 2"
"A - C - 1"
"A - C - 2"
"X - B - 1"
"X - B - 2"
"X - C - 1"
"X - C - 2"

我应该 select 运行 哪个

"A",  "", ""
"", "B", ""
"",  "", "1"
"",  "", "2"
"", "C", ""
"",  "", "1"
"",  "", "2"
"X",  "", ""
"", "B", ""
"",  "", "1"
"",  "", "2"
"", "C", ""
"",  "", "1"
"",  "", "2"

可能吗?

假设字符串中每个字符的位置是固定的,您可以使用字符串函数很容易地做到这一点。

select col1, col2, col3
from (  
  select distinct 
    substring(col1,1,1) col1, 
    null col2, 
    null col3, 
    substring(col1,1,1) ord 
  from t

  union all

  select distinct 
    null, 
    substring(col1,5,1), 
    null, 
    concat(substring(col1,1,1),substring(col1,5,1))
  from t

  union all

  select distinct 
    null, 
    null, 
    substring(col1,9,1),
    concat(substring(col1,1,1),substring(col1,5,1),substring(col1,9,1))
  from t  
) a order by ord;

Sample SQL Fiddle

这个查询会 return:

|   col1 |   col2 |   col3 |
|--------|--------|--------|
|      A | (null) | (null) |
| (null) |      B | (null) |
| (null) | (null) |      1 |
| (null) | (null) |      2 |
| (null) |      C | (null) |
| (null) | (null) |      1 |
| (null) | (null) |      2 |
|      X | (null) | (null) |
| (null) |      B | (null) |
| (null) | (null) |      1 |
| (null) | (null) |      2 |
| (null) |      C | (null) |
| (null) | (null) |      1 |
| (null) | (null) |      2 |

更新

如果您有固定长度的字符串,上面提供的答案是有效的 - 所有样本都考虑长度等于 1 的字符串。但是,如果您需要变长字符串,请按照以下步骤操作

SELECT col1, col2, col3
FROM (
  SELECT DISTINCT
    SUBSTRING_INDEX(col1, ' - ', 1) col1, 
    NULL col2, 
    NULL col3, 
    SUBSTRING_INDEX(col1, ' - ', 1) ord
  FROM t

  UNION ALL

  SELECT DISTINCT 
    NULL, 
    SUBSTRING_INDEX(SUBSTRING_INDEX(col1, ' - ', 2), ' - ', -1), 
    NULL, 
    CONCAT(SUBSTRING_INDEX(col1, ' - ', 1), SUBSTRING_INDEX(SUBSTRING_INDEX(col1, ' - ', 2), ' - ', -1)) ord
  FROM t

  UNION ALL

  SELECT DISTINCT
    NULL, 
    NULL,  
    SUBSTRING_INDEX(col1, ' - ', -1),
    CONCAT(SUBSTRING_INDEX(col1, ' - ', 1), SUBSTRING_INDEX(SUBSTRING_INDEX(col1, ' - ', 2), ' - ', -1), SUBSTRING_INDEX(col1, ' - ', -1)) ord
  FROM t
) a ORDER BY ord;