Выберите последнюю запись для каждой связанной категории, доступной на объекте - PullRequest
1 голос
/ 28 апреля 2010

У меня есть tblMachineReports со столбцами: Status (varchar), LogDate (datetime), Category (varchar) и MachineID (int).

Я хочу получить последнее обновление статуса из каждой категории для каждой машины, чтобы получить снимок последних статусов всех машин, уникальных для их MachineID.

Данные таблицы будут выглядеть как

Категория - Статус - MachineID - LogDate
ката - статус1 - 001 - дата1
ката - статус2 - 002 - дата2
catb - status3 - 001 - date2
catc - status2 - 002 - date4
ката - статус3 - 001 - дата5
catc - status1 - 001 - date6
catb - status2 - 001 - date7
ката - статус2 - 002 - дата8
catb - status2 - 002 - date9
catc - status2 - 001 - date10


Вкратце, у меня есть несколько компьютеров, сообщающих о нескольких статусах в этом tblMachineReports. Все строки создаются с помощью вставок, поэтому, по мере появления новых статусов, они, очевидно, будут дублирующими записями для машин. Ни один из столбцов не может быть предсказан, поэтому я не могу делать сравнения = некоторые жестко закодированные строки в любой части оператор выбора.


Для предоставленной мною таблицы желаемые результаты будут выглядеть следующим образом:

Категория - Статус - MachineID - LogDate
catc - status2 - 002 - date4
ката - статус3 - 001 - дата5
catb - status2 - 001 - date7
ката - статус2 - 002 - дата8
catb - status2 - 002 - date9
catc - status2 - 001 - date10

Как бы выглядел оператор select для достижения этой цели, получая последний статус для каждой категории на каждом компьютере с использованием MS SQL Server 2008? Я пробовал разные комбинации подзапросов в сочетании с совокупными значениями MAX (LogDates), а также с объединениями, группировкой, различиями и чем-то еще, но пока не нашел работающего решения.

Ответы [ 2 ]

3 голосов
/ 28 апреля 2010

Извинения, если вы уже пробовали это, но эта форма группировки и агрегации должна работать

select *
from tblMachineReports t
where LogDate = (select max(LogDate) from tblMachineReports t2 where t.machineID = t2.machineID and t.category = t2.category)

Попробуйте, может понадобиться тонкая настройка

2 голосов
/ 28 апреля 2010
 SELECT * FROM tblMachineReports MR1 
    WHERE NOT EXISTS
       (SELECT * FROM tblMachineReports MR2 WHERE
            MR2.Category = MR1.Category AND 
            MR2.MachineID = MR1.MachineID AND
            MR2.LogDate > MR1.LogDate)

Единственная проблема заключается в том, что если у вас есть одна и та же категория и машина более одного раза в одну и ту же дату, вы получите все записи за эту дату, а не только последнюю. Чтобы это исправить, измените LogDate на DATETIME, если у вас есть доступ к структуре базы данных, или добавьте в таблицу столбец идентификаторов с увеличивающимся числом и используйте его вместо LogDate в операторе SELECT.

[отредактировано для изменения <на> в последней строке SQL]

...