解决这个问题我已经坚持了好几天。我在SQL Server中有三个表:家庭表,资金表和桥接表Family_Funding。家庭表列出了每个家庭的所有家庭成员,例如:
家庭
id name Parent_id
----------- -------------------------------------------------- -----------
1 Father A NULL
2 Son A 1
3 Daughter A 1
4 Father B NULL
5 Mother B NULL
6 Daughter B 4
“资助”表列出了每年的所有资助计划。还包括这些计划的举办年份。
资金
id name year
----------- -------------------------------------------------- ----------
1 Funding A 2010-01-14
2 Funding B 2011-11-14
3 Funding C 2014-01-01
4 Funding D 2016-01-01
5 Funding E 2018-01-01
最后一个是桥接表,其中列出了一个(只有一个)家庭成员收到的资金。
家庭资助
id Family_id Funding_id
----------- ----------- -----------
1 1 1
2 1 2
3 1 3
4 2 4
5 3 5
从上一张表中我们可以看到,直到2014年,家庭A通过父亲A获得资金,在2016年他们通过儿子A获得资金,在2018年通过女儿A获得资金。
如何实现此结果: 我想查看家庭A的最新资金,很遗憾,我只能得到结果 E资金,因为最新的一笔资金是通过女儿A获得的。但是由于女儿A是家庭A的成员, ,结果应包括通过儿子A和父亲A的其他资助。
预期结果
Family_name Funding A Funding B Funding C Funding D Funding E
----------- --------- --------- --------- --------- ---------
Daughter A 1 1 1 1 1
任何帮助将不胜感激!谢谢!
答案 0 :(得分:0)
也许有一种更简洁的方法,但是它确实可以为您提供所需的东西。您应该看的主要部分是家庭的定义(A,B,C ...)。我使用的方法是:
LTRIM(RTRIM(RIGHT(fam.[Name],2)))
这是完整的代码。为了进行此练习,我将表数据放入表变量中。
DECLARE @Family TABLE (
Id BIGINT NOT NULL PRIMARY KEY,
[Name] VARCHAR(100) NOT NULL,
ParentId BIGINT NULL
);
INSERT INTO @Family
(Id, [Name], ParentId)
VALUES
(1,'Father A',NULL),
(2,'Son A',1),
(3,'Daughter A',1),
(4,'Father B',NULL),
(5,'Mother B',NULL),
(6,'Daughter B',4);
DECLARE @Funding TABLE (
Id BIGINT NOT NULL PRIMARY KEY,
[Name] VARCHAR(100) NOT NULL,
[Year] DATE NOT NULL
);
INSERT INTO @Funding
(Id, [Name], [Year])
VALUES
(1,'Funding A','2010-01-14'),
(2,'Funding B','2011-11-14'),
(3,'Funding C','2014-01-01'),
(4,'Funding D','2016-01-01'),
(5,'Funding E','2018-01-01');
DECLARE @FamilyFunding TABLE (
Id BIGINT NOT NULL PRIMARY KEY,
FamilyId BIGINT NOT NULL,
FundingId BIGINT NOT NULL
);
INSERT INTO @FamilyFunding
(Id, FamilyId, FundingId)
VALUES
(1,1,1),
(2,1,2),
(3,1,3),
(4,2,4),
(5,3,5);
WITH CTE AS (
SELECT
fam.[Name] AS FamilyName,
fun.[Name] AS FundingName,
fun.[Year],
LTRIM(RTRIM(RIGHT(fam.[Name],2))) AS Family,
ROW_NUMBER() OVER (PARTITION BY LTRIM(RTRIM(RIGHT(fam.[Name],2))) ORDER BY fun.[Year] DESC) AS RowNumber
FROM @FamilyFunding AS ff
INNER JOIN @Family AS fam
ON ff.FamilyId = fam.Id
INNER JOIN @Funding AS fun
ON ff.FundingId = fun.Id
),
FINAL AS (
SELECT
a.Family,
a.FamilyName AS MostRecentFamilyMember,
a.[Year] AS MostRecentYear,
b.FamilyName AS FamilyMember,
b.FundingName,
b.[Year],
b.RowNumber
FROM CTE AS a
INNER JOIN CTE AS b
ON a.Family = b.Family
WHERE a.RowNumber = 1
)
SELECT
MostRecentFamilyMember,
MAX([Funding A]) AS FundingA,
MAX([Funding B]) AS FundingB,
MAX([Funding C]) AS FundingC,
MAX([Funding D]) AS FundingD,
MAX([Funding E]) AS FundingE
FROM (
SELECT
f.Family,
f.MostRecentFamilyMember,
f.MostRecentYear,
f.FamilyMember,
f.FundingName,
f.[Year],
f.RowNumber,
1 AS IsUsed
FROM FINAL AS f
) AS b
PIVOT (
MAX(IsUsed)
FOR FundingName IN ([Funding A], [Funding B], [Funding C], [Funding D], [Funding E])
) AS p
GROUP BY
MostRecentFamilyMember;