在家庭关系表

时间:2017-09-18 20:00:21

标签: sql sql-server tsql parent-child recursive-query

我的源数据库中有一张表,用于将一个人与他的妻子/丈夫及其子女(如果有的话)联系起来。

与孩子的关系可以通过妻子或丈夫,但只有一个成年人与孩子之间的关系,而丈夫和妻子之间只有一种关系。与配偶的关系不一定是与孩子/孩子有关系的成年人。

我想创建一个输出,其中我拥有每个人和他们家庭的唯一ID。但我似乎无法理解如何获得结果。

以下我的源数据示例。

+--------+------+
| FromID | ToID |
+--------+------+
|      1 |    2 |
|      2 |    3 |
|      2 |    4 |
|      5 |    6 |
|      6 |    7 |
|      8 |    9 |
+--------+------+

   CREATE TABLE [dbo].[Relations](
            [FromID] [int] NULL,
            [ToID] [int] NULL
        ) 
        INSERT [dbo].[Relations] ([FromID], [ToID]) VALUES (1, 2)
        INSERT [dbo].[Relations] ([FromID], [ToID]) VALUES (2, 3)
        INSERT [dbo].[Relations] ([FromID], [ToID]) VALUES (2, 4)
        INSERT [dbo].[Relations] ([FromID], [ToID]) VALUES (5, 6)
        INSERT [dbo].[Relations] ([FromID], [ToID]) VALUES (6, 7)
        INSERT [dbo].[Relations] ([FromID], [ToID]) VALUES (8, 9)

在此示例数据中:

  • 1人与2人结婚,2人2人(3,4)(4个家庭)
  • 第5个人与6人结婚,6人有1个孩子(7)(3个家庭)
  • 8人与9人结婚,没有孩子(2个家庭)

以下是理想的结果:

+----------+----------+
| PersonID | FamilyID |
+----------+----------+
|        1 |        1 |
|        2 |        1 |
|        3 |        1 |
|        4 |        1 |
|        5 |        2 |
|        6 |        2 |
|        7 |        2 |
|        8 |        3 |
|        9 |        3 |
+----------+----------+

2 个答案:

答案 0 :(得分:0)

首先,您需要找出每个家庭的丈夫并分配和身份证明。您查找的ID不会显示为ng serve --prod --aot.

<强> SQL DEMO

[FromID]

<强>输出

enter image description here

然后只使用递归查询来获取[ID]

的所有家庭成员

https://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx

编辑:

因为您的树只有两个级别的深度,您可以使用WITH husband as ( SELECT R1.[FromID] as [ID], ROW_NUMBER() OVER (ORDER BY R1.[FromID]) as rn FROM [Relations] R1 LEFT JOIN [Relations] R2 ON R1.[FromID] = R2.[ToID] WHERE R2.[FromID] IS NULL ) SELECT * FROM husband 来完成它,但如果您想要处理单亲族,我会发现问题。

<强> SQL DEMO

JOINS

<强>输出

enter image description here

答案 1 :(得分:0)

以下是实现此结果的另一种方法:

SELECT DISTINCT
  COALESCE(h.husband, d.dependents) AS id,
  COALESCE(d.familyid, h.familyid) AS familyid
FROM (SELECT
            r.ToID AS dependents,
            DENSE_RANK() OVER (ORDER BY COALESCE(r2.Fromid, r.Fromid)) AS familyid
      FROM Relations r
      LEFT JOIN Relations r2
        ON r.[FromID] = r2.ToID) d
FULL JOIN (SELECT
              COALESCE(r2.Fromid, r.Fromid) AS husband,
              DENSE_RANK() OVER (ORDER BY COALESCE(r2.Fromid, r.Fromid)) AS familyid
           FROM Relations r
           LEFT JOIN Relations r2
             ON r.[FromID] = r2.ToID) h
  ON d.dependents = h.husband