Применение функции агрегата MIN к полю BIT
Я хочу написать следующий запрос:
SELECT ..., MIN(SomeBitField), ...
FROM ...
WHERE ...
GROUP BY ...
Проблема в том, что SQL Server не нравится, когда я хочу рассчитать минимальное значение битового поля, он возвращает ошибку Operand data type bit is invalid for min operator
.
Я мог бы использовать следующее обходное решение:
SELECT ..., CAST(MIN(CAST(SomeBitField AS INT)) AS BIT), ...
FROM ...
WHERE ...
GROUP BY ...
Но есть ли что-то более элегантное? (Например, может быть агрегатная функция, которую я не знаю, и которая вычисляет логические and
битовых значений в поле.)
Ответы
Ответ 1
Поскольку для BIT
существует только два варианта, просто используйте оператор case:
SELECT CASE WHEN EXISTS (SELECT 1 FROM ....) THEN 1 ELSE 0 END AS 'MinBit'
FROM ...
WHERE ...
Это имеет то преимущество, что
- Не форсировать сканирование таблицы (индексы в областях
BIT
почти никогда не будут использоваться)
- Короткое замыкание TWICE (один раз для
EXISTS
и снова для CASE
)
Это немного больше кода для написания, но это не должно быть ужасно. Если у вас есть несколько значений для проверки, вы всегда можете инкапсулировать свой больший набор результатов (со всеми критериями JOIN
и FILTER
) в CTE
в начале запроса, а затем ссылаться на это в операторах CASE
.
Ответ 2
Один параметр - MIN(SomeBitField+0)
. Он читает хорошо, с меньшим шумом (который я бы квалифицировал как элегантность).
Тем не менее, это больше хак-иш, чем опция CASE
. И я ничего не знаю о скорости/эффективности.
Ответ 3
Попробуйте следующее
Примечание:. Минимальное представление. А агрегатная функция. Макс. представление или агрегатная функция.
SELECT ..., MIN(case when SomeBitField=1 then 1 else 0 end), MIN(SomeBitField+0)...
FROM ...
WHERE ...
GROUP BY ...
тот же результат
Ответ 4
Этот запрос является лучшим решением:
SELECT CASE WHEN MIN(BitField+0) = 1 THEN 'True' ELSE 'False' END AS MyColumn
FROM MyTable
Когда вы добавляете BitField + 0, он автоматически будет выглядеть как int
Ответ 5
select min(convert(int, somebitfield))
или если вы хотите сохранить результат как бит
select convert(bit, min(convert(int, somebitfield)))
Ответ 6
AVG (CAST (boolean_column AS FLOAT)) OVER (...) AS BOOLEAN_AGGREGATE
Дайте нечеткое логическое значение:
-
1 указывают, что все True;
-
0 указывают, что все false;
-
значение между] 0..1 [указать частичное совпадение и может быть некоторым процентом истины.