父和子存储在同一个表中时显示父子关系

时间:2010-11-07 03:50:47

标签: sql sql-server tsql

我有如下的SQL Server表结构:

ID    Name     ParentID
-----------------------
1     Root       NULL
2     Business   1
3     Finance    1
4     Stock      3

我想在我的网页中显示详细信息,如

ID    Name     ParentName
-------------------------
1     Root      -
2     Business  Root
3     Finance   Root
4     Stock     Finance    

如何构建SQL查询?

7 个答案:

答案 0 :(得分:8)

试试这个......

SELECT a.ID, a.Name, b.Name AS 'ParentName'
FROM TABLE AS a LEFT JOIN TABLE AS b on a.ParentID = b.ID

使用左连接,查询将找不到要为NULL加入的任何内容,并为ParentName列返回空白。

编辑:

如果您不希望“父级”列为空,但希望显示“ - ”破折号,请使用此查询。

SELECT a.ID, a.Name, COALESCE(b.Name,'-') AS 'ParentName'
FROM TABLE AS a LEFT JOIN TABLE AS b on a.ParentID = b.ID

答案 1 :(得分:4)

假设SQL Server 2005+,请使用这样的递归CTE:

WITH hierarchy AS (
  SELECT t.id,
         t.name,
         t.parentid,
         CAST(NULL AS VARCHAR(50)) AS parentname
    FROM YOUR_TABLE t
   WHERE t.parentid IS NULL
  UNION ALL
  SELECT x.id,
         x.name,
         x.parentid,
         y.name
    FROM YOUR_TABLE x
    JOIN hierarchy y ON y.id = x.parentid)
SELECT s.id,
       s.name,
       s.parentname
  FROM hierarchy s

NULL的CASTing可能看起来很奇怪,但SQL Server默认将数据类型设置为INT,除非以我在查询中看到的方式指定。

答案 2 :(得分:4)

我正面临着同样的情况。 我想从同一张表中获取特定父级的所有子级列表,因为在MySQL 8以下未提供MySQL 递归CTE

我已经解决了递归存储过程的问题。为此,我们需要将 max_sp_recursion_depth 设置为递归存储过程调用。

我的表格结构如下

enter image description here

我的存储过程(具有递归)如下:

DROP PROCEDURE IF EXISTS getAllChilds;
DELIMITER $$
SET @@SESSION.max_sp_recursion_depth=25; $$
CREATE PROCEDURE getAllChilds (IN inId int(11), INOUT list_obj text, IN end_arr CHAR(1))
BEGIN
    DECLARE stop_cur INTEGER DEFAULT 0;
    DECLARE _id INTEGER DEFAULT 0;
    DECLARE _name VARCHAR(20) DEFAULT 0;
    DEClARE curSelfId CURSOR FOR SELECT id, name FROM new_table where parentId = inId;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET stop_cur = 1; 
    OPEN curSelfId; 
    getSelfId: LOOP
        FETCH curSelfId INTO _id, _name;
        IF stop_cur = 1 THEN LEAVE getSelfId; END IF;
        IF list_obj is null or list_obj = "" then 
            SET list_obj = CONCAT("[","{",'"name":"',_name,'","id":"',_id,'"',"}");
        else 
            SET list_obj = CONCAT(list_obj,',', "{",'"name":"',_name,'","id":"',_id,'"',"}");
        end if;
        CALL getAllChilds(_id,list_obj,"");
    END LOOP getSelfId;
    CLOSE curSelfId;
    IF end_arr is not null and end_arr != "" then 
        SET list_obj = CONCAT(list_obj,end_arr);
        SELECT @ids;
    end if;
END$$
DELIMITER ;

要调用此存储过程,我们需要传递3个参数,

  1. 父母身份
  2. 空/空对象
  3. 结束数组符号。(仅附加最后一个对象而不是所有对象)。

    CALL getAllChilds(1,@ ids,']');

使用此存储过程,您可能会在JSON字符串中获取所有级别的子级。 您可以解析此json字符串,并使用任何JSONparser在任何对象中进行转换。

我们可以将this answer包装在存储过程中,以将其用于任何编程语言(如JAVA)中。 我们将其包装到存储过程中,因为我们不能在查询中使用:= 。 在这里,我们使用 find_in_set 函数。 我的存储过程(无递归)。

DROP PROCEDURE IF EXISTS getAllChilds;
DELIMITER $$
CREATE PROCEDURE getAllChilds (IN inId int(11))
BEGIN
    select id,
        name,
        parentid
    from  
        (select * from new_table
        order by parentid, id) new_table,
        (select @pv := inId) initialisation
    where   
        find_in_set(parentid, @pv) > 0
        and @pv := concat(@pv, ',', id);
END$$
DELIMITER ;

要调用此存储过程,我们只需要父ID。

CALL getAllChilds(1);

答案 3 :(得分:3)

SELECT CH.ID, CH.NAME, ISNULL(PA.NAME, '-') AS "PARENTNAME"
FROM TBL CH
LEFT OUTER JOIN TBL PA
ON CH.PARENTID = PA.ID

答案 4 :(得分:1)

我认为以下查询可行。我没有测试过它。

SELECT
ID
, name
, (CASE WHEN parent_name IS NULL THEN '-' ELSE parent_name END)
FROM
RELATIONS
, (SELECT 
parentID
, name AS parent_name
FROM
RELATION) PARENT
WHERE
RELATIONS.parentId = PARENT.parentId

基本上,我正在做的是选择父信息,并将其与每个元组联系起来。

答案 5 :(得分:0)

这是一种简单的方法:

SELECT ID,Name,(SELECT TOP 1 Name FROM Table t WHERE t.ParentID=ParentID) AS ParentName FROM Table

答案 6 :(得分:0)

像之前发布的人一样,它需要是一个递归函数。 可能有多种情况 - 多个子节点的一个父节点(级别1层次结构) 父1有子1 父1有子2 孩子到多个孩子(2级层次结构) 等等。

我的示例有父曲线ID和子曲线ID。 例如,

WITH hierarchy AS
(select UT.parent_curve_id as origin, UT.*
from myTable UT
WHERE UT.parent_curve_id IN ( 1027455, 555)
UNION ALL
select h.origin, UT.*
from myTable UT
JOIN hierarchy h ON h.child_curve_id = UT.parent_curve_id
)
SELECT *
from hierarchy 
order by unique_key
相关问题