2010-08-16 4 views
1

Я уверен, что это общий запрос, но я не знаю, как его запросить формально.Найти максимальное значение для каждого родителя

Я столкнулся с этим давным-давно, когда был в армии. Солдат имеет несколько тестов физической пригодности, но первичный тест, который считается самым последним. Солдат также имеет несколько квалификаций стрельбы, но только самая последняя квалификация к назначенному оружию значительна.

Как создать представление, в котором перечислены наиболее значимые дочерние элементы родителя?

+0

Вы можете размещать примеры данных до «перечисляя» и после? – Oded

+0

Для какой базы данных - SQL Server или Sybase? Версия также будет полезна. –

ответ

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 
              ) 

Это предполагает, что у пасьянса не может быть двух значений тестового времени для теста пригодности или стрельбы 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 
Смежные вопросы