Проверьте все связанные записи, прежде чем возвращать значение - PullRequest
0 голосов
/ 04 мая 2018

Итак, я пытаюсь создать коллекцию в SCCM, которую я хотел бы дать мне список активов (name0), с которыми не связан файл .ide, более новый, чем 21 день После идентификации я могу уйти и выяснить, почему эти ресурсы не обновляются.

Пока что я написал следующий запрос в SSMS, прежде чем настроить его в SCCM, но стало очевидно, что это неправильный подход.

SELECT DISTINCT v_GS_SYSTEM.Name0

FROM v_GS_SYSTEM inner join v_GS_SoftwareFile 
    ON v_GS_SoftwareFile.ResourceID = v_GS_SYSTEM.ResourceID

WHERE (DATEDIFF(day, v_GS_SoftwareFile.ModifiedDate, getdate()) >=21)

       AND NOT

      (DATEDIFF(day, v_GS_SoftwareFile.ModifiedDate, getdate()) <=21)

      AND
      v_GS_SoftwareFile.FileName like '/%.ide/'

ORDER BY v_GS_SYSTEM.Name0;

Этот код возвращает «правильные» значения, но не учитывает тот факт, что актив может все еще есть новые файлы ide, связанные с ним, что противоречит цели этого упражнения.

Итак (я думаю!) Мой вопрос, есть ли способ проверить, есть ли у Name0 какие-либо связанные ModifiedDate записи? не более 21 дня и возвращать значение, только если эта проверка возвращает true / false?

РЕДАКТИРОВАТЬ: отредактированный ответ @MatBailie с выводом: enter image description here

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Чтобы присоединить все '*.ide' файлы к их ресурсам, но только для ресурсов, в которых не было файлов '*.ide', измененных за последние 21 день ...

SELECT
    s.Name0,
    f.FilePath,
    f.FileName
FROM
(
    SELECT
        *,
        MAX(ModifiedDate) OVER (PARTITION BY ResourceID)   AS ResourceMaxModifiedDate
    FROM
        v_GS_SoftwareFile
    WHERE
        FileName LIKE '%.ide'
)
    AS f
INNER JOIN
    v_GS_SYSTEM         AS s
        ON  s.ResourceID =  f.ResourceID
WHERE
    f.ResourceMaxModifiedDate <= DATEADD(DAY, -21, GETDATE())
ORDER BY
    s.Name0,
    f.FilePath,
    f.FileName

Чтобы получить все ресурсы, в которых не было файлов '*.ide', измененных за последние 21 день ...

SELECT
    s.Name0
FROM
    v_GS_SYSTEM         AS s
WHERE
    NOT EXISTS (
      SELECT *
        FROM v_GS_SoftwareFile    AS f
       WHERE f.FileName     LIKE '%.ide'
         AND f.ResourceID     =  s.ResourceID
         AND f.ModifiedDate  >=  DATEADD(DAY, -21, GETDATE())
    )
ORDER BY
    s.name0

Рассмотрите ваши индексы в этих таблицах в зависимости от того, каким запросом вы закончите Индекс покрытия более (ResourceID, ModifiedDate) был бы полезен. Также был бы полезен флаг для типа файла (LIKE '*.ide' потребует сканирования строк для поиска совпадений, его нельзя решить с помощью обычного индекса) .

0 голосов
/ 04 мая 2018

Вы можете просто добавить дополнительное предложение EXISTS, где вы проверяете это.

Я полагаю, что вы пытаетесь написать запрос:

SELECT DISTINCT vs.Name0
    , vsf.FilePath
    , vsf.FileName
FROM v_GS_SYSTEM vs
INNER JOIN v_GS_SoftwareFile vsf
    ON vsf.ResourceID = vs.ResourceID
WHERE (DATEDIFF(day, vsf.ModifiedDate, getdate()) >= 21)
    AND NOT (DATEDIFF(day, vsf.ModifiedDate, getdate()) <= 21) -- this seems a bit redundant and might even exclude some rows where the result is exactly (21 * 24) hours
    AND vsf.FileName LIKE '/%.ide/'
    AND NOT EXISTS (
        SELECT 1
        FROM v_GS_SoftwareFile vsf2
        WHERE vsf2.ModifiedDate > GETDATE() - 21
            AND vsf2.ResourceId = vsf.ResourceId
        )
ORDER BY vs.Name0;

Вы можете изменить чек TRUE / FALSE, сохранив или удалив NOT в AND NOT EXISTS.

Изменить:

Поскольку вы упоминали проблемы с производительностью, проверьте, есть ли у вас некластеризованные идексы:

  • в столбце ResourceId в таблице v_GS_SoftwareFile (я действительно надеюсь, что это не представление, но v_ в начале заставляет меня думать, что это так).
  • в столбце ResourceID в таблице v_GS_SYSTEM ( такой же комментарий здесь )
...