1

У меня есть tblMachineReports со столбцами: Status (varchar), LogDate (datetime), Category (varchar) и MachineID (int).Выберите последнюю запись для каждой категории, связанной с объектами

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

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

Категория - Статус - MachineID - LogDate
Ката - STATUS1 - 001 - date1
Ката - СОСТОЯНИЕ 2 - 002 - date2
catb - СОСТОЯНИЕ 3 - 001 - date2
CATC - СОСТОЯНИЕ 2 - 002 - date Ката - СОСТОЯНИЕ 3 - 001 - date5
CATC - STATUS1 - 001 - date6
catb - СОСТОЯНИЕ 2 - 001 - date7
Ката - СОСТОЯНИЕ 2 - 002 - date8
catb - СОСТОЯНИЕ 2 - 002 - date9
CATC - СОСТОЯНИЕ 2 - 001 - date10


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


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

Категория - Статус - MachineID - LogDate
CATC - СОСТОЯНИЕ 2 - 002 - date Ката - СОСТОЯНИЕ 3 - 001 - date5
catb - СОСТОЯНИЕ 2 - 001 - date7
Ката - СОСТОЯНИЕ 2 - 002 - date8
catb - СОСТОЯНИЕ 2 - 002 - date9
CATC - СОСТОЯНИЕ 2 - 001 - date10

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

+0

Спасибо за помощь всем людям, это сообщество абсолютно феноменально в своей базе знаний и времени отклика. – Simpleton

+0

Я добавил тег наибольшего числа на группу, потому что эквивалентный вопрос был задан десятками раз на SO. Но мне пришлось удалить один из тэгов из-за ограничения на 5 тегов. –

+0

Спасибо за ваш ответ Простой, мой ответ действительно больше не совместим с существующими стандартами базы данных. Я изменил свой ответ с вашего комментария – TerrorAustralis

ответ

3

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

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

Попробуйте сделать это, возможно, потребуется какая-то тонкая настройка

+0

Вы хотите, чтобы категория, а не статус, в предложении WHERE коррелированного подвыбора, я думаю. –

+0

Я изменил решение, которое я думаю, так как вы разместили это. У меня уже нет подзапроса – TerrorAustralis

+0

Я не специалист по SQL Server, но я думаю, что вы были ближе в первый раз. В этой версии вы получите несколько значений состояния, а не только последний, назад, и нет никакого неагрегированного значения LogDate в наборе результатов, который будет использоваться в предложении HAVING. –

2
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]

+0

Поскольку LogDate - это DateTime в моей схеме, я считаю, что это точно до миллисекунды, а статистическая вероятность встречных дат записи настолько низка для этого приложения, что заявленная проблема должна быть незначительной. – Simpleton

+0

Затем вы должны быть установлены. В случае столкновения на миллисекундах, предполагая, что вам не важно, какой статус вы получите, вы можете группировать результирующий набор и принимать статус MAX или MIN. Это даст вам только одну строку результатов. –

+0

Я думаю, что знак <должен быть> больше знака, я создал тестовый набор данных, и, используя ваш запрос, <знак возвратил самую раннюю запись для каждой категории на каждой машине, я добавил «заказ по LogDate» до конца ваш запрос и с <все даты раньше, чем даты, которые я верну с помощью знака>. Я ошибаюсь, или, может быть, я недостаточно подробно рассказывал об этом описании проблемы, мне нужны последние данные о дате записи для каждой категории на каждой машине. – Simpleton