在家庭关系上添加家庭 ID 列 Table
add Family ID Column on Family Relations Table
我的源数据库中有一个 table 将一个人与其妻子/丈夫以及他们的 child 人(如果有的话)联系起来。
与child人的关系可以通过妻子或丈夫,但其中一个成年人与child人只有一个关系,而与child人之间只有一个关系丈夫和妻子。与配偶有关系的成年人不一定是与 child/children.
有关系的成年人
我想创建一个输出,其中包含每个人及其家庭的唯一 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 children (3,4)(4 口之家)
- 第 5 个人与第 6 个人结婚,第 6 个人有 1 个 child (7)(3 人家庭)
- 第 8 人与第 9 人结婚,没有 child人(2 人的家庭)
下面是想要的结果:
+----------+----------+
| PersonID | FamilyID |
+----------+----------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 1 |
| 5 | 2 |
| 6 | 2 |
| 7 | 2 |
| 8 | 3 |
| 9 | 3 |
+----------+----------+
首先你需要找出每个家庭的丈夫并分配ID。您查找未显示为 [FromID]
的 ID
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
输出
然后只需使用递归查询来获取该 [ID]
的所有家庭成员
https://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx
编辑:
因为你的树只有两层深度,你可以使用 JOINS
来做到这一点,但如果你想处理单亲家庭,我可以看到问题。
WITH husbands as (
SELECT ROW_NUMBER() OVER (ORDER BY R1.[FromID]) as [familyID],
R1.[FromID] as [ID]
FROM [Relations] R1
LEFT JOIN [Relations] R2
ON R1.[FromID] = R2.[ToID]
WHERE R2.[FromID] IS NULL
), wifes as (
SELECT H.[familyID], R1.[ToID] as [ID]
FROM husbands H
JOIN Relations R1
ON H.[ID] = R1.[FromID]
), childrens as (
SELECT H.[familyID], R2.[ToID] as [ID]
FROM husbands H
JOIN Relations R1
ON H.[ID] = R1.[FromID]
JOIN Relations R2
ON R1.[ToID] = R2.[FromID]
)
SELECT * FROM husbands UNION
SELECT * FROM wifes UNION
SELECT * FROM childrens
输出
这是另一种实现此结果的方法:
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
我的源数据库中有一个 table 将一个人与其妻子/丈夫以及他们的 child 人(如果有的话)联系起来。
与child人的关系可以通过妻子或丈夫,但其中一个成年人与child人只有一个关系,而与child人之间只有一个关系丈夫和妻子。与配偶有关系的成年人不一定是与 child/children.
有关系的成年人我想创建一个输出,其中包含每个人及其家庭的唯一 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 children (3,4)(4 口之家)
- 第 5 个人与第 6 个人结婚,第 6 个人有 1 个 child (7)(3 人家庭)
- 第 8 人与第 9 人结婚,没有 child人(2 人的家庭)
下面是想要的结果:
+----------+----------+
| PersonID | FamilyID |
+----------+----------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 1 |
| 5 | 2 |
| 6 | 2 |
| 7 | 2 |
| 8 | 3 |
| 9 | 3 |
+----------+----------+
首先你需要找出每个家庭的丈夫并分配ID。您查找未显示为 [FromID]
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
输出
然后只需使用递归查询来获取该 [ID]
的所有家庭成员https://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx
编辑:
因为你的树只有两层深度,你可以使用 JOINS
来做到这一点,但如果你想处理单亲家庭,我可以看到问题。
WITH husbands as (
SELECT ROW_NUMBER() OVER (ORDER BY R1.[FromID]) as [familyID],
R1.[FromID] as [ID]
FROM [Relations] R1
LEFT JOIN [Relations] R2
ON R1.[FromID] = R2.[ToID]
WHERE R2.[FromID] IS NULL
), wifes as (
SELECT H.[familyID], R1.[ToID] as [ID]
FROM husbands H
JOIN Relations R1
ON H.[ID] = R1.[FromID]
), childrens as (
SELECT H.[familyID], R2.[ToID] as [ID]
FROM husbands H
JOIN Relations R1
ON H.[ID] = R1.[FromID]
JOIN Relations R2
ON R1.[ToID] = R2.[FromID]
)
SELECT * FROM husbands UNION
SELECT * FROM wifes UNION
SELECT * FROM childrens
输出
这是另一种实现此结果的方法:
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