用于从两个表中选择ID列和最新日期的SQL语法

时间:2012-06-05 12:11:12

标签: sql sql-server-2008 union distinct

我有一个系统,用户可以完成两种类型的测试。我需要获得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)

我很高兴使用Test_User_Id获取所有不同UNION的列表,如下所示:

SELECT Test_User_Id FROM Test_1_Results
UNION
SELECT Test_User_Id FROM Test_2_Results

我可以使用ORDER BY Date_Of_Completion DESC轻松地从其中一个表中对结果进行排序,但我不知道如何使用UNION进行排序,或者这是否是最佳的继续进行方式。< / p>

最终我希望能够将此查询包装在其他内容中:

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

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

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

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

4 个答案:

答案 0 :(得分: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

答案 1 :(得分: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;

答案 2 :(得分: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

答案 3 :(得分: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