Запрос T-SQL для получения имени компьютера, который не отправлял запросы к базе данных в течение 60 дней

У меня есть таблица Queries, в которой отслеживается каждый запрос к базе данных с отметкой date_time и именем компьютера.

Для одного и того же компьютера могут быть тысячи строк, каждая из которых имеет разную отметку date_time.

Если компьютер не сделал запрос в течение 60 дней, то его необходимо идентифицировать.

Я знаю, как проверить каждую запись, чтобы узнать, не прошло ли для этой конкретной записи запроса больше 60 дней.

Я не знаю, как просмотреть все записи для этого конкретного компьютера, чтобы определить, превышает ли МАЛЕНЬКАЯ отметка date_time более 60 дней, и если да, то показать ее в результатах.

Пожалуйста, простите, так как я новичок в SQL-запросах. Спасибо.

Я пытался:

select computer_name 
from queries 
where date_time > 20240508000000

Я хочу показать только computer_name ЕСЛИ у него нет ни одной записи возрастом менее 60 дней, потому что это означает, что он не использовался для запроса в течение 2 месяцев и его необходимо идентифицировать.

Приведенный выше пример неверен, поскольку в нем будут показаны ВСЕ записи длительностью более 60 дней.

Примеры данных и ожидаемые результаты будут очень полезны. У вас есть отдельный список всех машин? Почему вы храните даты как целые числа?

Charlieface 09.07.2024 00:28
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
90
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я предлагаю это без тестирования и при условии, что временная метка имеет тип данных datetime или аналогичный. Идея состоит в том, чтобы получить самую молодую временную метку для каждого компьютера с помощью группировки (агрегирования), а затем отфильтровать те, чья самая молодая временная метка старше 60 дней по сравнению с текущим моментом (GETDATE()).

После того, как стала доступна дополнительная информация, я обновил решение. Я не знаю тип данных, который создает такие значения, как 202407080000US или 20240508000000, поэтому я использую довольно грубый способ преобразования в тип данных DATE, игнорируя части времени. Я также не знаю, какая часть этих входных данных — месяц, а какая — день, поэтому проверьте это.

;WITH prep AS(
SELECT
  computer_name
  ,date = CONVERT(DATE, LEFT(CONVERT(NVARCHAR(100), date_time), 8))
FROM queries
)
SELECT
  computer_name
  ,youngest = MAX(date)
FROM prep
GROUP BY computer_name
HAVING MAX(date) <= DATEADD(DAY, -60, CONVERT(DATE,GETDATE()))
-- This works, too, but it is better to keep 
-- the column as much as possible outside of functions:
--HAVING DATEDIFF(DAY, MAX(date), CONVERT(DATE,GETDATE())) > 60

Добавление индекса в queries(computer_name, date_time) может повысить производительность, если вы обнаружите, что ваш запрос выполняется медленнее, чем хотелось бы.

T N 09.07.2024 02:56

@TN — для запроса GROUP BY computer_name SQL Server не будет использовать преимущества того, что date_time является вторым ключевым столбцом в индексе при поиске MAX — если вам нужен такой план, вам нужно выполнить эффективный запрос TOP 1 для каждого computer_name (подпункт запрос, apply, рекурсивное CTE)

Martin Smith 09.07.2024 08:59

@ Der U — получена следующая ошибка: Сообщение 241, уровень 16, состояние 1, строка 1. Не удалось выполнить преобразование при преобразовании даты и/или времени из строки символов. Кроме того, я не упомянул, что данные/время такие же, как 202407080000US.

Korgon 09.07.2024 18:50

Я только что изменил ответ. Не могли бы вы уточнить тип данных date_time? Откуда это? Какое программное обеспечение? Другая СУБД?

Der U 09.07.2024 19:10

@MartinSmith - Хорошая мысль. Похоже, я предполагал оптимизацию индекса, которая не реализована. Лучшее, что я мог сделать, это индексное сканирование. (рабочий пример). Однако если таблица содержит другие «широкие» столбцы, такие как текст запроса, «узкий» индекс все равно может сократить количество операций чтения.

T N 09.07.2024 19:15

Вместо преобразования каждого значения текста даты вы можете определить и применить ограничение текста даты с помощью чего-то вроде: DECLARE @CutoffDate DATE = DATEADD(day, -60, GETDATE()), DECLARE @CutoffText VARCHAR(50) = CONVERT(VARCHAR(8), @CutoffDate, 112) + '000000', а затем исходный ответ изменить с помощью HAVING MAX(date_time) < @CutoffDate. Полный запрос: SELECT computer_name, youngest = MAX(date_time) FROM queries GROUP BY computer_name HAVING MAX(date_time) < @CutoffDate.

T N 09.07.2024 19:26

@ Der U — Это может сработать, но я не уверен, как указать запросы таблицы в сложном операторе. Если я поставлю From в первый выбор, это выдаст ошибку «Неверный синтаксис рядом с «from», даже если имена столбцов разрешаются. Если я удалю это и поставлю query.date_time, возникнет ошибка: идентификатор, состоящий из нескольких частей, не может быть связан. Но я думаю, что оно почти у цели!

Korgon 09.07.2024 19:27

@ Der U - date_time равно varchar(16). Я не уверен в исходном программном обеспечении, просто отправляю запрос к базе данных с помощью SSMS на SQL-сервер.

Korgon 09.07.2024 19:36

@colemd1 Во-первых, я облажался и забыл предложение FROM в cte, надеюсь, мне наконец удалось отредактировать это и сделать работоспособным. Во-вторых, в зависимости от среды, в которой вы это запускаете, вам может потребоваться опустить точку с запятой в начале. Пожалуйста, попробуйте еще раз.

Der U 09.07.2024 19:39

@ Дер Ю - ТЫ МУЖЧИНА!!! Спасибо, это работает.

Korgon 09.07.2024 19:43

@ colemd1 Рад помочь. Еще хотелось бы знать, откуда Вы взяли эти значения. varchar(16) просто означает, что сервер sql хранит его как строку. Этот формат может вызвать у вас проблемы, особенно когда временная часть становится актуальной. Почему иногда в последних двух позициях выдаются два нуля, а иногда «США»? Тебе стоит проверить, что там происходит.

Der U 09.07.2024 19:56

Другие вопросы по теме

Похожие вопросы

Использовать значение из одного запроса SQL в качестве имени столбца в другом запросе SQL
Процедура FINTAG_INSTEADOFINSERTTRIGGER, строка 41. Невозможно вставить явное значение в столбец метки времени
Ошибка «Не удалось преобразовать строку символов в уникальный идентификатор». при использовании UNION ALL
Поле идентификатора объекта JPA с последовательностью SQL Server 2022
Функция выполняется медленно (12 с) в PHP, но быстро (до секунды) в SSMS. Каковы некоторые области расследования?
Запрос на объединение данных строк в каждой группе
Поток данных Azure Synapse: невозможно использовать параметр в сценариях Pre SQL
Запретить обновление столбца на основе существующего значения
Как SQL Server допускает использование нескольких одинаковых псевдонимов в одном операторе SELECT?
Неверный синтаксис рядом с ',' при выполнении SQL-запроса в Spring JPA, но успешно выполняется в базе данных