Я пытаюсь создать коллекцию на основе запросов в SCCM, которая будет нацелена на все компьютеры с четырьмя определенными программами. Эти четыре программы также могут быть установлены на компьютерах, которые не имеют ничего общего с приложением, на которое я пытаюсь ориентироваться, поэтому в коллекцию их не следует включать. В коллекцию должны быть включены только ПК со ВСЕМИ 4 установленными программами.
Наивная реализация ниже не работает, но вот логика того, что я хочу:
SELECT SMS_R_SYSTEM.Name
FROM SMS_R_System
INNER JOIN SMS_G_System_ADD_REMOVE_PROGRAMS
ON SMS_G_System_ADD_REMOVE_PROGRAMS.ResourceID = SMS_R_System.ResourceId
INNER JOIN SMS_G_System_ADD_REMOVE_PROGRAMS_64
ON SMS_G_System_ADD_REMOVE_PROGRAMS_64.ResourceID = SMS_R_System.ResourceId
WHERE SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName LIKE "ArcGIS Engine%" AND
SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName LIKE "Java 8%" AND
SMS_G_System_ADD_REMOVE_PROGRAMS_64.DisplayName LIKE "Microsoft SQL Server%" AND
SMS_G_System_ADD_REMOVE_PROGRAMS_64.DisplayName = "SQL Server Management Studio"
Как вы получаете логическое AND
здесь?
Обратите внимание, что интерфейс SCCM требует WQL, а не T-SQL для запросов на сбор данных. Следовательно, оператор COUNT недоступен (и я считаю, что предложение HAVING работает по-другому).
Если вам нужно проверить несколько записей, вы, вероятно, хотите, чтобы они существовали.
Большая часть того, что вы описываете, больше подходит для сценария powershell или dos; если приложение хранит свою конфигурацию в базе данных SQL, нам нужны только детали таблиц и выборочные данные.
Не лучший способ, но это будет легко отладить для вас. Вы можете присоединяться к одной и той же таблице несколько раз, вам просто нужно каждый раз давать ей разные псевдонимы, каждое из этих объединений можно использовать для фильтрации в определенной программе:
SELECT S.Name
FROM SMS_R_System s
INNER JOIN SMS_G_System_ADD_REMOVE_PROGRAMS p1
On p1.ResourceID = S.ResourceId
INNER JOIN SMS_G_System_ADD_REMOVE_PROGRAMS p2
On p2.ResourceID = S.ResourceId
INNER JOIN SMS_G_System_ADD_REMOVE_PROGRAMS p3
On p3.ResourceID = S.ResourceId
INNER JOIN SMS_G_System_ADD_REMOVE_PROGRAMS p4
On p4.ResourceID = S.ResourceId
WHERE p1.DisplayName LIKE 'ArcGIS Engine%'
AND P2.DisplayName LIKE 'Java 8%'
AND p3.DisplayName LIKE 'Microsoft SQL Server%'
AND p4.DisplayName = 'SQL Server Management Studio'
Почему это решение было отклонено? Если он работает неправильно, не лучше ли оставить комментарий, почему он работает неправильно, вместо того, чтобы наказывать автора за бесплатный совет?
Это решение оказалось правильным. Когда я задавал вопрос, я не понял, что SCCM использует WQL, который не поддерживает оператор COUNT, как это делает T-SQL. Кроме того, SCCM хранит 32- и 64-разрядные программы в разных таблицах, так что это решение на самом деле лучше подходит для этого сценария (хотя это скорее хитрый хак).
Вы можете использовать 4 предложения EXISTS для поиска каждой отдельной программы. По сути, это то же решение, что и опубликованное Эндрю.
В качестве альтернативы вы можете использовать что-то вроде этого:
SELECT SMS_R_SYSTEM.Name
FROM SMS_R_System INNER JOIN SMS_G_System_ADD_REMOVE_PROGRAMS
ON SMS_G_System_ADD_REMOVE_PROGRAMS.ResourceID = SMS_R_System.ResourceId
WHERE SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName LIKE "ArcGIS Engine%" OR
SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName LIKE "Java 8%" OR
SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName LIKE "Microsoft SQL Server%" OR
SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName = "SQL Server Management Studio"
GROUP BY SMS_R_SYSTEM.Name
HAVING COUNT(DISTINCT SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName) = 4
Я не думаю, что нам нужно так много информации, это запутывает проблему. Я рекомендую простой минимальный воспроизводимый пример с примерами данных, желаемыми результатами и вашей попыткой.