0

我有一个类似这样的 MySQL 表:

ID    elementName  subElementOfID

1        1            
2        2            
3        4            
4        5            
5        9            
6        3            
7        6            
8        7            
9       71            8
10       8            
11      10            
12      72            8
13      73            8

元素不一定是数字,但可以是 varchars。“subElementOfID”列表示该元素(例如“71”)是 ID X 元素的子元素。在此示例中,ID 为 9、12 和 13 的元素是 ID 为 8 的元素的子元素。

目标:

以数字或字母数字顺序(取决于但并不重要)对该表进行排序,将标记为子元素的元素直接排序在其父元素之下。在这种情况下,按数字顺序排序的 SELECT 输出应如下所示:

ID    elementName  subElementOfID

 1        1            
 2        2            
 6        3            
 3        4            
 4        5            
 7        6            
 8        7            
 9       71            8
12       72            8
13       73            8
10        8            
 5        9            
11       10            

稍后在 PHP 中处理输出。我宁愿不使用 PHP 解决方案,而是使用 SQL-Select 以正确的顺序为我提供表格。

非常感谢任何帮助或建议。

由于这是我的第一个 Stackoverflow 问题,我希望我已经收集了所有重要事实并准备提供更多信息 :-)

拉尔夫


我找到了一个涉及 SELF JOIN 和 UNION 的解决方案。这可能过于复杂,我非常想要一个更简单的 SELECT。

SELECT ID, element FROM 
((SELECT t1.ID, t1.elementName as element, t2.elementName AS element2, t1.subElementOfID 
FROM test t1
LEFT JOIN test t2 ON t2.ID = t1.subElementOfID
WHERE t1.subElementOfID IS NOT NULL)

UNION

(SELECT ID, elementName AS element, elementName AS element2, subElementOfID FROM test 
WHERE subElementOfID IS NULL)

ORDER BY element2, subElementOfID, element) tu

用户 xpda(感谢您的输入!)建议按字符串连接排序。如果 elementName 列实际上包含名称而不是数字,我认为这实际上是一个好主意,因为我并不完全满足于数字的字母数字顺序。在现实生活中,我在此列中有整数,但可能会说服我的老板使用口头名称而不是数字。试图根据我对 xpda 答案的理解编写一个 SQL 表达式:

SELECT t1.ID, t1.elementName, t1.subElementOfID AS parentName
FROM test2 t1
LEFT JOIN test2 t2 ON t1.subElementOfID=t2.ID
ORDER BY IF(ISNULL(t2.elementName), t1.elementName, CONCAT(CAST(t2.elementName AS CHAR), CAST(t1.elementName AS CHAR)));

所以所有子元素都在其父元素下排序,但“10”自然介于 1 和 2 之间......

有什么进一步的建议吗?

4

2 回答 2

1

您可以对两列(第二列+第一列)的串联进行排序(排序)。您可能需要先转换为字符串。

于 2013-02-23T21:06:31.363 回答
0

好的,我将回答我自己的问题 :-) Barmar 的评论以及 xpda 的回答都有帮助。他们没有提供 SQL,但引导我朝着正确的方向前进。非常感谢您!

我有两个可行的解决方案,每个都有它的优点:

  1. 我通过连接字符串进行简单的自连接和排序,我用一些前导零来丰富单个数字。在其他情况下 - 对 varchar 值进行排序时 - 这些零不是必需的:

    SELECT t1.ID, t1.elementName, t1.subElementOfID AS parentName
    FROM table t1
    LEFT JOIN table t2 ON t1.subElementOfID=t2.ID
    ORDER BY IF(ISNULL(t2.elementName), LPAD(t1.elementName, 2, '0'), CONCAT(CAST(LPAD(t2.elementName, 2, '0') AS CHAR), CAST(t1.elementName AS CHAR)));
    
  2. 上面带有自连接和 UNION 的 SQL 工作正常,即使它有点长:

    SELECT ID, element FROM 
    ((SELECT t1.ID, t1.elementName as element, t2.elementName AS element2, t1.subElementOfID 
    FROM table t1
    LEFT JOIN table t2 ON t2.ID = t1.subElementOfID
    WHERE t1.subElementOfID IS NOT NULL)
    
    UNION
    
    (SELECT ID, elementName AS element, elementName AS element2, subElementOfID FROM table
    WHERE subElementOfID IS NULL)
    
    ORDER BY element2, subElementOfID, element) tu
    
于 2013-02-24T15:24:12.463 回答