2010-08-16 56 views
1

我确定这是一个常见的要求,但我不知道如何正式要求。找到每个家长的最高价值

我很久以前在军队时遇到过这个问题。一名士兵有多次体能测试,但最近的主要测试是计数。这名士兵也拥有多种枪法资格,但只有最近分配的武器才具有重要意义。

你如何创建一个视图,项目的父母最重要的孩子?

+0

您可以发布“逐项说明”前后数据的例子吗? – Oded 2010-08-16 17:18:40

+0

对于哪个数据库--SQL Server或Sybase?版本也会有帮助。 – 2010-08-16 17:27:07

回答

1

用途:

SELECT p.*, x.* 
    FROM PARENT p 
    JOIN CHILD x ON x.parent_id = p.id 
    JOIN (SELECT c.id, 
       c.parent_id, 
       MAX(c.date_column) AS max_date 
      FROM CHILD c 
     GROUP BY c.id, c.parent_id) y ON y.id = x.id 
            AND y.parent_id = x.parent_id 
            AND y.max_date = x.date 

假设的SQL Server 2005+:

WITH summary AS (
    SELECT p.*, 
      c.*, 
      ROW_NUMBER() OVER (PARTITION BY p.id 
            ORDER BY c.date DESC) AS rank 
     FROM PARENT p 
     JOIN CHILD c ON c.parent_id = p.id) 
SELECT s.* 
    FROM summary s 
WHERE s.rank = 1 
1

虽然我不太清楚你是通过 “逐项” 意味着什么,你可以做一些事情,像这样:

Select .. 
From Soldier 
    Left Join FitnessTest 
     On FitnessTest.SoldierId = Soldier.Id 
      And FitnessTest.TestDate = (
             Select Max(FT1.TestDate) 
             From FitnessTest As FT1 
             Where FT1.SoldierId = FitnessTest.SoldierId 
             ) 
    Left Join MarksmanshipTest 
     On MarksmanshipTest.SoldierId = Soldier.Id 
      And MarksmanshipTest.TestDate = (
              Select Max(MT1.TestDate) 
              From MarksmanshipTest As MT1 
              Where MT1.SoldierId = MarksmanshipTest.SoldierId 
              ) 

这假设一个士兵不能有两个测试日期时间值的健身测试或markmansh ip测试。

0

从前面的两个答案,但也许更详细一点没有显著differnce:

create table soldier (soldierId int primary key, 
    name varchar(100)) 
create table fitnessTest (soldierId int foreign key references soldier, 
    occurred datetime, result int) 
create table marksmanshipTest (soldierId int foreign key references soldier, 
    occurred datetime, result int) 

;with 
mostRecentFitnessTest as 
(
    select 
     fitnessTest.soldierId, 
     fitnessTest.result, 
     row_number() over (order by occurred desc) as row 
    from fitnessTest 
), 
mostRecentMarksmanshipTest as 
(
    select 
     marksmanshipTest.soldierId, 
     marksmanshipTest.result, 
     row_number() over (order by occurred desc) as row 
    from marksmanshipTest 
) 
select 
    soldier.soldierId, 
    soldier.name, 
    mostRecentFitnessTest.result, 
    mostRecentMarksmanshipTest.result 
from soldier 
    left outer join mostRecentFitnessTest on 
     mostRecentFitnessTest.soldierId = soldier.soldierId 
     and mostRecentFitnessTest.row = 1 
    left outer join mostRecentMarksmanshipTest on 
     mostRecentMarksmanshipTest.soldierId = soldier.soldierId 
     and mostRecentMarksmanshipTest.row = 1