95 votes

Application de la fonction d'agrégation MIN à un champ BIT

Je veux écrire la requête suivante:

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

Le problème est, SQL Server ne l'aime pas, quand je veux calculer la valeur minimale d'un champ de bits , il renvoie l'erreur en Operand data type bit is invalid for min operator.

Je pourrais utiliser la solution de contournement suivante:

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

Mais, est-il quelque chose de plus élégant? (Par exemple, il pourrait y avoir une fonction d'agrégation, que je ne connais pas, et qui évalue la logique and de la valeur des bits dans un champ.)

177voto

Ben Mosher Points 5005

Personnellement, j'aime bien l'approche de MIN(SomeBitField+0) . Cela ressemble beaucoup plus à ce qui est prévu (ce que j'aurais tendance à qualifier d'élégance).

Cela dit, c'est un peu plus compliqué que l'option CASE . Et je ne peux rien dire sur la vitesse / efficacité.

36voto

JNK Points 32743

Puisqu'il y a seulement deux options pour l' BIT, il suffit d'utiliser une instruction de cas:

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

Ceci a l'avantage de:

  • Ne pas forcer une analyse de table (index sur BIT champs assez beaucoup n'obtiennent jamais utilisés)
  • Le court-circuit deux fois (une fois pour EXISTS et encore pour l' CASE)

Il est un peu plus de code à écrire, mais il ne devrait pas être terrible. Si vous avez plusieurs valeurs à vérifier, vous pouvez toujours encapsuler votre plus grand ensemble de résultats (avec tous les JOIN et FILTER critères) en CTE au début de la requête, puis de référence que dans l' CASE des déclarations.

9voto

Israel Margulies Points 1713

Cette requête est la meilleure solution:

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

Lorsque vous ajoutez le BitField +0, il devient automatiquement comme int

6voto

Waleed A.K. Points 426

Essayez la remarque suivante : Min représente et fonction d'agrégat, Max représente ou fonction d'agrégat

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

même résultat

-6voto

Beth Points 6644

Ou changez le type de données de bit en int.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X