2

我有一个系统,用户可以在其中完成两种类型的测试。我需要获取DISTINCT按最新测试完成日期排序的用户列表。

为此目的,这些表格也可以如下列出:

Test_Users
 - Test_User_Id (int)

Test_1_Results
 - Test_1_Result_Id (int)
 - Test_User_Id (int)
 - Date_Of_Completion (datetime)

Test_2_Results
 - Test_2_Result_Id (int)
 - Test_User_Id (int)
 - Date_Of_Completion (datetime)

我可以很高兴地使用 a 获得所有不同Test_User_Id's的列表,UNION如下所示:

SELECT Test_User_Id FROM Test_1_Results
UNION
SELECT Test_User_Id FROM Test_2_Results

而且我可以使用 a 轻松地对这些表之一的结果进行排序,ORDER BY Date_Of_Completion DESC但我不知道如何使用 the 来执行此操作,UNION或者这是否是进行的最佳方式。

最终,我希望能够将此查询包装在其他查询中,例如:

SELECT *
FROM Test_Users
WHERE Test_User_Id IN (
    //The query i am asking about
)
WHERE some_criteria

但到目前为止,我在使用 a 时没有任何运气这样做,UNION而且我不确定我做错了什么。

我尝试这样做的原因是管理员用户需要能够查看已完成测试的每个人的列表,其中最近完成的内容位于顶部。

我对 SQL 相当熟悉,但我以前从未真正使用过UNION运算符。

4

4 回答 4

3

这应该工作

 SELECT Test_User_Id, max(Date_Of_Completion) AS doc
 FROM ( 
     SELECT Test_User_Id, Date_Of_Completion FROM Test_1_Results
       UNION ALL
     SELECT Test_User_Id , Date_Of_Completion FROM Test_2_Results 
 ) AS temptab
 GROUP BY Test_User_Id
 ORDER BY doc DESC
于 2012-06-05T12:17:32.537 回答
2
;WITH x(u,d) AS 
(
  SELECT u = Test_User_Id, d = MAX(Date_Of_Completion) 
    FROM dbo.Test_1_Results GROUP BY Test_User_Id
  UNION ALL
  SELECT Test_User_Id, MAX(Date_Of_Completion) 
    FROM dbo.Test_2_Results GROUP BY Test_User_Id
),
y AS 
(
  SELECT u, d, rn = ROW_NUMBER() OVER (PARTITION BY u ORDER BY d DESC)
  FROM x
)
SELECT Test_User_Id = u, Date_Of_Completion = d
FROM y
WHERE rn = 1;
于 2012-06-05T12:24:33.160 回答
1
SELECT t.Test_User_Id, max(Date_Of_Completion)
FROM Test_Users t
INNER JOIN
   (SELECT Test_User_Id, Date_Of_Completion FROM Test_1_Results
    UNION
    SELECT Test_User_Id, Date_Of_Completion FROM Test_2_Results) aux on aux.Test_User_Id = t.Test_User_Id
GROUP BY t.Test_User_Id
于 2012-06-05T12:18:03.337 回答
1

我喜欢原始问题的 ejb_guy 答案。如果问题被扩展,以至于您还想知道每个用户的最新结果的测试类型和结果 ID,那么我相信以下内容将起作用(未经测试),并且应该非常有效。

with All_Tests as (
  select Test_User_Id,
         Date_Of_Completion,
         'Test1' as Test_Type,
         Test_1_Result_Id as Result_Id
    from Test_1_Results
  union all
  select Test_User_Id,
         Date_Of_Completion,
         'Test2' as Test_Type,
         Test_2_Result_Id as Result_Id
    from Test_2_Results
),
Ranked_Tests as (
  select rank() over( partition by Test_User_Id
                      order by Date_Of_Completion desc,
                               Test_Type,
                               Result_Id
                    ) as Test_Rank,
         Test_User_Id,
         Date_Of_Completion,
         Test_Type,
         Result_Id
    from All_Tests
)
select Test_User_Id,
       Date_Of_Completion,
       Test_Type,
       Result_Id
  from Ranked_Tests
 where Test_Rank=1
 order by Date_Of_Completion desc, Test_User_Id
于 2012-06-05T14:50:42.440 回答