使用SQL来抓住父母和父母所在的孩子。孩子们都在同一张桌子上

时间:2017-12-21 15:51:20

标签: sql-server sql-server-2008 sql-server-2005

我有一个包含父级和子级的表。现在,我可以单独调用表:

Select * FROM inventory WHERE subID=0 // parents

通过父母循环

Select * from inventory where subID=parentID

我的问题是,有没有办法形成一个SQL语句来抓取父项和属于它的子项,所以..

//SQL Results would look like this
Parent
 - Child
 - Child
Parent
 - Child
 - Child
 - Child
etc..

更新

现在我知道这是什么了,这是我的尝试,但这没有结果。 id = 0表示它是父母。我做错了什么?

WITH children AS (

    SELECT id, parent_id
    FROM inventory
    WHERE id = 0

    UNION ALL

    SELECT a.id , a.parent_id
    FROM inventory a
    JOIN children b ON b.parent_id = a.id
)
    SELECT id, parent_id
    FROM children

这是工作代码的样子:

;WITH cte AS (
    SELECT DISTINCT id, parent_id, dateOn, capacity, status, instructorID, rowNum = ROW_NUMBER() OVER (ORDER BY id ASC)
    FROM inventory
    WHERE parent_id = 0 AND active='True' AND cID=1

    UNION ALL

    SELECT a.id, a.parent_id, a.dateOn, a.capacity, a.status, a.instructorID, b.rowNum
    FROM inventory a
    JOIN cte b  ON a.parent_id = b.id
    WHERE a.parent_id <> 0 AND active='True' AND cID=1
)
    SELECT id, parent_id, dateOn, capacity, status, (SELECT count(aID) FROM appointments WHERE id=cte.id) as totalCount
    FROM cte
    ORDER BY rowNum, id

1 个答案:

答案 0 :(得分:1)

编辑:

我想我现在已经弄明白了。 CTE中的rowNum用于对最终选择中的记录进行排序。

;WITH children AS (
    SELECT DISTINCT id, parent_id, rowNum = ROW_NUMBER() OVER (ORDER BY id ASC)
    FROM inventory
    WHERE parent_id = 0

    UNION ALL

    SELECT a.id , a.parent_id, b.rowNum
    FROM inventory a
    JOIN children b  ON a.parent_id = b.id
    WHERE a.parent_id <> 0    
)
    SELECT id, parent_id
    FROM children
    ORDER BY rowNum, id

使用问题中的完整查询进行第二次编辑:

要对dateOn进行排序,您只需将其添加到ORDER BY子句的开头即可。然后你最终得到这个:

;WITH cte AS (
    SELECT DISTINCT id, parent_id, dateOn, capacity, status, instructorID, rowNum = ROW_NUMBER() OVER (ORDER BY id ASC)
    FROM inventory
    WHERE parent_id = 0 AND active='True' AND cID=1

    UNION ALL

    SELECT a.id, a.parent_id, a.dateOn, a.capacity, a.status, a.instructorID, b.rowNum
    FROM inventory a
    JOIN cte b  ON a.parent_id = b.id
    WHERE a.parent_id <> 0 AND active='True' AND cID=1
)
    SELECT id, parent_id, dateOn, capacity, status, (SELECT count(aID) FROM appointments WHERE id=cte.id) as totalCount
    FROM cte
    ORDER BY dateOn, rowNum, id

让我们分解查询,看看发生了什么:

&#39;主播&#39; CTE是

SELECT DISTINCT id, parent_id, dateOn, capacity, status, instructorID, rowNum = ROW_NUMBER() OVER (ORDER BY id ASC)
FROM inventory
WHERE parent_id = 0 AND active='True' AND cID=1

这是从inventory获取所有父记录,并添加一个rownumber,我们可以使用它来关联父级和所有子级,以便在最终选择中进行排序。

CTE的递归部分是

SELECT a.id, a.parent_id, a.dateOn, a.capacity, a.status, a.instructorID, b.rowNum
FROM inventory a
JOIN cte b  ON a.parent_id = b.id
WHERE a.parent_id <> 0 AND active='True' AND cID=1

在查询的这一部分中,cte是对锚查询中父记录的递归引用。所以我们在这里将非父记录加入到父记录中。我们使用父级rowNum,因此父级及其子级都将具有此字段的相同值。

然后,最终的select语句将返回CTE中的所有行。我们首先按dateOn排序,以便共享相同dateOn的所有父/子记录将在一起。接下来我们按rowNum订购,以便每个家长与其子女一起。最后,我们对id进行排序,假设父母的id值小于他们的孩子。如果父母的id更大,那么我们可以通过parent_id进行排序,以便父记录(parent_id = 0)出现在他们的子女之前。