如何根据SQL Server 2008中的日期选择所有父记录和前一个最上面的子记录
我使用的是在SQLServer2008上运行的供应商提供的数据库。有两个表跟踪测试。对于表A中的每个记录,表B中可能有零条、一条或多条记录。对于同一用户,表A中也可能有多条测试。关系为TableA.UserID=TableB.UserID。表B中的试验可在表A之前或之后进行 我需要选择表A中的所有记录,如果表B中的测试是由同一用户在表A中的测试之前进行的,则数据来自表B,但仅来自上一个子记录。两个表的结构相似:如何根据SQL Server 2008中的日期选择所有父记录和前一个最上面的子记录,sql,sql-server,database,sql-server-2008,select,Sql,Sql Server,Database,Sql Server 2008,Select,我使用的是在SQLServer2008上运行的供应商提供的数据库。有两个表跟踪测试。对于表A中的每个记录,表B中可能有零条、一条或多条记录。对于同一用户,表A中也可能有多条测试。关系为TableA.UserID=TableB.UserID。表B中的试验可在表A之前或之后进行 我需要选择表A中的所有记录,如果表B中的测试是由同一用户在表A中的测试之前进行的,则数据来自表B,但仅来自上一个子记录。两个表的结构相似: **TABLE A** TestID INTEGER PRIMARY KEY, Us
**TABLE A**
TestID INTEGER PRIMARY KEY,
UserID INTEGER,
TestDate DATE,
Score INTEGER
TABLE B
TestID INTEGER PRIMARY KEY,
UserID INTEGER,
TestDate Date,
Score INTEGER
样本数据
TABLE A
TestID UserID TestDate Score
1 100 2014-02-15 80
2 101 2014-02-20 100
3 102 2014-02-22 90
4 102 2014-03-10 70
TABLE B
TestID UserID TestDate Score
1000 100 2014-02-01 55
1007 100 2014-02-05 85
1012 100 2014-02-20 95
1034 102 2014-02-12 65
1205 102 2014-03-05 75
1986 101 2014-03-10 45
我想退回的是:
UserID TestA_ID TestADate TestAScore TestB_ID TestBDate TestBScore
100 1 2014-02-15 80 1007 2014-02-05 85
101 2 2014-02-20 100 NULL NULL NULL
102 3 2014-02-22 90 1034 2014-02-12 65
102 4 2014-03-10 70 1205 2014-03-05 75
我知道如何通过在WHERE子句中使用左外部联接和按日期筛选,将前面的表B的所有行联接到表A的行,并且我知道如何从表B中获取顶行,但是我还没有弄清楚如何获取表A中记录日期之前出现的顶级子记录。如有任何帮助,将不胜感激。谢谢。您可以使用T-SQL中的外部应用来完成此操作 对于TableA中的每个记录,我们在TableB中查找同一用户的记录,但测试日期早于TableA中的测试日期,并且我们还在TableB中订购测试,以确保我们从TableB中获得最新的测试(但仍然早于TableA中的测试日期) 或者另一个选项可能是使用ROW_NUMBER()窗口函数从TableB中查找记录。我有一种预感,这一个不会执行得很好,因为它需要在TableA中运行两次,但如果不运行测试,就无法确定
SELECT
A.[UserID],
A.[TestID] [TestA_ID],
A.[TestDate] [TestADate],
A.[Score] [TestAScore],
B.[TestB_ID],
B.[TestBDate],
B.[TestBScore]
FROM [TableA] A
LEFT JOIN
(
SELECT
ROW_NUMBER() OVER (PARTITION BY A.[UserID], A.[TestID] ORDER BY B.[TestDate] DESC) [rn],
A.[UserID],
A.[TestID] [TestA_ID],
B.[TestID] [TestB_ID],
B.[TestDate] [TestBDate],
B.[Score] [TestBScore]
FROM [TableA] A
INNER JOIN [TableB] B
ON A.[UserID] = B.[UserID]
AND A.[TestDate] > B.[TestDate]
) B
ON A.[UserID] = B.[UserID]
AND A.[TestID] = B.[TestA_ID]
AND B.[rn] = 1
谢谢你的建议,但你的查询结果集不是我想要的。我需要将TableA中每个记录的数据与TableB中测试日期早于TableA中测试日期的顶层子记录的数据连接起来。使用您提供的示例数据,此代码将准确返回您作为所需输出提供的内容。请你更新你的帖子,加入一个代码不起作用的场景,这样我可以调整代码以满足你的需要吗?Eilert,谢谢你的回复。我用你的代码得到了不同的结果。代码返回的第四行:
103 4 2014-03-10 70 NULL
我将尝试更新示例,使其更清楚我想要什么。谢谢。我已经更新了我的答案。让我知道这是否是你所需要的。艾勒特,非常感谢。外部应用解决方案非常有效。我真的很感谢你抽出时间来帮忙。现在我只需要把我的头绕在申请上。
SELECT
A.[UserID],
A.[TestID] [TestA_ID],
A.[TestDate] [TestADate],
A.[Score] [TestAScore],
B.[TestB_ID],
B.[TestBDate],
B.[TestBScore]
FROM [TableA] A
LEFT JOIN
(
SELECT
ROW_NUMBER() OVER (PARTITION BY A.[UserID], A.[TestID] ORDER BY B.[TestDate] DESC) [rn],
A.[UserID],
A.[TestID] [TestA_ID],
B.[TestID] [TestB_ID],
B.[TestDate] [TestBDate],
B.[Score] [TestBScore]
FROM [TableA] A
INNER JOIN [TableB] B
ON A.[UserID] = B.[UserID]
AND A.[TestDate] > B.[TestDate]
) B
ON A.[UserID] = B.[UserID]
AND A.[TestID] = B.[TestA_ID]
AND B.[rn] = 1