Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Applying the MIN aggregate function to a BIT field

I want to write the following query:

SELECT   ..., MIN(SomeBitField), ... FROM     ... WHERE    ... GROUP BY ... 

The problem is, SQL Server does not like it, when I want to calculate the minimum value of a bit field it returns the error Operand data type bit is invalid for min operator.

I could use the following workaround:

SELECT   ..., CAST(MIN(CAST(SomeBitField AS INT)) AS BIT), ... FROM     ... WHERE    ... GROUP BY ... 

But, is there something more elegant? (For example, there might be an aggregate function, that I don't know, and that evaluates the logical and of the bit values in a field.)

like image 410
pyon Avatar asked Aug 09 '11 14:08

pyon


People also ask

How do you use the MIN aggregate function?

Returns the smallest value of an expression over a group of rows. The return value has the same type as the expression data type. The MIN analytic function differs from the aggregate function, in that it returns the minimum value of an expression over a group of rows within a window.

What is MIN aggregate function in SQL?

The aggregate function SQL MIN() is used to find the minimum value or lowest value of a column or expression. This function is useful to determine the smallest of all selected values of a column.

How do I add a bit field in SQL?

To insert a new value to the BIT column, use INSERT statement: INSERT INTO table_name (bit_column) VALUES (1); You can also use TRUE and FALSE as the inputs for the BIT columns, SQL Server will automatically convert them as follow: TRUE will be converted to 1.

What is the use MIN () and COUNT () functions?

COUNT() – returns the number of values. MAX() – returns the maximum value. MIN() – returns the minimum value.


2 Answers

One option is MIN(SomeBitField+0). It reads well, with less noise (which I would qualify as elegance).

That said, it's more hack-ish than the CASE option. And I don't know anything about speed/efficiency.

like image 97
Ben Mosher Avatar answered Oct 14 '22 04:10

Ben Mosher


Since there are only two options for BIT, just use a case statement:

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

This has the advantage of:

  • Not forcing a table scan (indexes on BIT fields pretty much never get used)
  • Short circuiting TWICE (once for EXISTS and again for the CASE)

It is a little more code to write but it shouldn't be terrible. If you have multiple values to check you could always encapsulate your larger result set (with all the JOIN and FILTER criteria) in a CTE at the beginning of the query, then reference that in the CASE statements.

like image 26
JNK Avatar answered Oct 14 '22 05:10

JNK