Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何根据SQL Server 2008中的日期选择所有父记录和前一个最上面的子记录_Sql_Sql Server_Database_Sql Server 2008_Select - Fatal编程技术网

如何根据SQL Server 2008中的日期选择所有父记录和前一个最上面的子记录

如何根据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

我使用的是在SQLServer2008上运行的供应商提供的数据库。有两个表跟踪测试。对于表A中的每个记录,表B中可能有零条、一条或多条记录。对于同一用户,表A中也可能有多条测试。关系为TableA.UserID=TableB.UserID。表B中的试验可在表A之前或之后进行

我需要选择表A中的所有记录,如果表B中的测试是由同一用户在表A中的测试之前进行的,则数据来自表B,但仅来自上一个子记录。两个表的结构相似:

**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