Я показываю сетку с родительскими данными, и мне нужно показать значок, если у него есть соответствующие дочерние строки. Моя БД находится в SQL Server 2008 . Позвольте мне упростить, у меня есть следующие две таблицы -
Заказ (PK: ID)
Файл (ПК: FileID, FK: OrderID)
Order
может иметь ноль или более файлов, связанных с ним. Таблица File
имеет столбец OrderID
, который содержит ссылку FK на Order
. Теперь я отображаю сетку, в которой перечислены все Orders
, и я хочу отобразить изображение значка, показывающее, есть ли у Order
дочерние строки (файлы) или нет.
Вот хитрый способ, который я экспериментировал, но не уверен, насколько он эффективен / масштабируем -
SELECT DISTINCT o.ID, o.OrderNum, ...
,(CASE f.ID/f.ID WHEN 1 THEN 1 ELSE 0 END) as FilesExist
...
FROM Order AS o LEFT OUTER JOIN dbo.FileHeader as f ON f.OrderID = o.ID
Оператор CASE
, кажется, работает идеально, как требуется. Он вернет 1, если существует один или несколько файлов, иначе 0. Если существует несколько строк, то он попытается повторить строку Order
, для которой я добавил DISTINCT, и я не выбираю f.ID
но f.ID/f.ID
, который будет 1 (он существует) и 0 для нуля (не существует). Я узнал, что JOIN лучше, чем встроенные операторы SELECT COUNT(*)
.
Я проверил, и это работает, но мне нужно мнение эксперта и нужно убедиться, что это лучший способ сделать это. Это очень простой пример, но мой оператор SELECT
сложен, так как есть много поисков, и он будет дорогостоящим, поэтому мне нужно убедиться, что он масштабируемый.
Спасибо.
РЕДАКТИРОВАТЬ # 1:
В заключение - либо это будет внутренний SELECT с COUNT (*)
SELECT c.ClaimNo,(SELECT COUNT(*) FROM dbo.FileHeader AS f WHERE f.ClaimID = c.ID ) AS FilesHExist
FROM dbo.Claim AS c
или подход LEFT OUTER JOIN , о котором я упоминал.
SELECT DISTINCT c.ClaimNo, (CASE fh.ID / fh.ID WHEN 1 THEN 1 ELSE 0 END) AS FilesHExist
FROM dbo.Claim AS c LEFT OUTER JOIN dbo.FileHeader AS fh ON fh.ClaimID = c.ID
Прикреплены два изображения плана выполнения запроса. Пожалуйста, предложите, какой из них лучше.