Применение агрегатной функции MIN к битовому полю


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

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 61

7 ответов:

так как есть только два варианта 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 заявления.

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

тем не менее, это более Хак-иш, чем . И я ничего не знаю о скорости/эффективности.

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

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

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

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

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

при добавлении битового поля+0 он автоматически становится как int

select min(convert(int, somebitfield))

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

select convert(bit, min(convert(int, somebitfield)))

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

дайте нечеткое булево:

  • 1 указывают, что все это правда;

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

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

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

CONVERT(BIT, MIN(CONVERT(INT, BitField))) as BitField