Применение агрегатной функции MIN к полю BIT - PullRequest
69 голосов
/ 09 августа 2011

Я хочу написать следующий запрос:

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 значений битов в поле.)

Ответы [ 7 ]

133 голосов
/ 09 мая 2012

Один вариант - MIN(SomeBitField+0). Хорошо читается, с меньшим количеством шума (что я бы назвал элегантностью).

Тем не менее, он более хакерский, чем опция CASE. И я ничего не знаю о скорости / эффективности.

31 голосов
/ 09 августа 2011

Поскольку для BIT есть только две опции, просто используйте оператор case:

SELECT CASE WHEN EXISTS (SELECT 1 FROM ....) THEN 1 ELSE 0 END AS 'MinBit'
FROM ...
WHERE ...

Преимущество этого:

  • Не заставлять сканирование таблицы (индексы для полей BIT почти никогда не используются)
  • Короткое замыкание ДВАЖДЫ (один раз для EXISTS и еще раз для CASE)

Это немного больше кодаписать, но это не должно быть ужасно.Если у вас есть несколько значений для проверки, вы всегда можете инкапсулировать свой больший набор результатов (со всеми критериями JOIN и FILTER) в CTE в начале запроса, а затем сослаться на это в операторах CASE.

6 голосов
/ 08 июля 2016
select min(convert(int, somebitfield))

или если вы хотите сохранить результат как бит

select convert(bit, min(convert(int, somebitfield)))
6 голосов
/ 25 ноября 2013

Попробуйте следующее Примечание: Мин. Представляют И агрегирующая функция, Макс. Представляют Или агрегирующая функция

SELECT   ..., MIN(case when SomeBitField=1 then 1 else 0 end), MIN(SomeBitField+0)...
FROM     ...
WHERE    ...
GROUP BY ...

тот же результат

6 голосов
/ 15 апреля 2013

Этот запрос является лучшим решением:

SELECT CASE WHEN MIN(BitField+0) = 1 THEN 'True' ELSE 'False' END AS MyColumn
 FROM MyTable

Когда вы добавляете BitField + 0, он автоматически становится как int

3 голосов
/ 22 марта 2018

Этот маленький кусочек кода всегда работал со мной как шарм:

CONVERT(BIT, MIN(CONVERT(INT, BitField))) as BitField
2 голосов
/ 06 января 2017

AVG (CAST (boolean_column AS FLOAT)) OVER (...) AS BOOLEAN_AGGREGATE

Дайте нечеткое логическое значение:

  • 1 означает, что все верно;

  • 0 означают, что все ложно;

  • значение между] 0..1 [указывает на частичное совпадение и может быть некоторым процентом правды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...