如何在SQL中使用按位标志值进行选择

时间:2015-04-20 20:00:54

标签: sql sql-server bit-manipulation bitwise-operators

我在SQL Server数据库中有两个表。一个表BusinessOperations具有关于此业务对象的各种信息,另一个表OperationType纯粹是一个按位标志表,如下所示:

| ID | Type    | BitFlag |
|  1 | Basic-A |   -2    |
|  2 | Basic   |   -1    |
|  3 | Type A  |   0001  |
|  4 | Type B  |   0002  |
|  5 | Type C  |   0004  |
|  6 | Type D  |   0008  |
|  7 | Type E  |   0016  |
|  8 | Type F  |   0032  |

BitFlag列是varchar列,以'0001'作为示例插入位标志。在BusinessOperations表中,有一列使用这些表的应用程序根据应用程序UI中选择的内容更新它。例如,我有一种类型,其中选择了BasicType AType B类型。 BusinessOperations中的列值为3.

基于此,我正在尝试编写一个查询,它将显示如下:

| ID | Name |  Description  |      OperationType    |
|  1 | Test |     Test      | Basic, Type A, Type B |

以下是BusinessOperations表的实际布局(Basic-ABasic是位列:

| ID | Name |  Description  | Basic-A | Basic | OperationType |
|  1 | Test |     Test      |    0    |   1   |       3       |

没有任何内容可以将这两个表相互关联,因此我无法执行连接。我对按位操作非常缺乏经验,并且对于如何构造用于分析此数据的select查询完全不知所措。我觉得它需要STUFFCASE,但我不知道如何才能显示这些类型,而不仅仅是生成的BitFlag。

SELECT ID, Name, Description, OperationType
FROM OperationType
ORDER BY ID

2 个答案:

答案 0 :(得分:0)

在BusinessOperations表中,Basic-A和Basic字段是位字段,这只是另一种说法,该值只能是1或0.可以将其视为布尔值True / False。因此,在您的查询中,您可以检查每个内容,以确定是否包含“基本A”和“基本”。

OperationType可能是一个id,您可以在OperationsType表中查找以获取Type和BitFlag。如果不完全理解您的数据,看起来您可以为该部分进行连接。希望这是正确的大方向。如果没有,请告诉我。

答案 1 :(得分:0)

由于您要将OperationType中的标记存储为VARCHAR,因此您需要做的第一件事就是将CONVERTCAST字符串添加到一个数字中我们可以进行适当的按比例比较。我对SQL Server略有不熟悉,但在演员表之前你可能需要remove the leading zeroes。因此,我们所需SQL中的OperationType列看起来像

CONVERT(INT, BitFlag)

然后,将其与我们的OperationType列进行比较将类似于

CONVERT(INT, BitFlag) & OperationType

完整查询看起来像(原谅我再次缺乏SQL Server专业知识):

SELECT bo.ID, bo.Name, bo.Description, ot.Type
FROM BusinessOperations AS bo
JOIN OperationType AS ot
ON CONVERT(INT, ot.BitFlag) & OperationType <> 0

上述查询将有效地为您提供OperationTypes的列表。如果您在一行中绝对需要它们,请参阅other answers以了解如何在SQL Server中模拟GROUP_CONCAT之类的内容。 免责声明:加入位掩码并不能保证性能。

此答案未解决的另一个问题是您的旧版Basic和Basic-A字段。就个人而言,我会做两件事之一:

  1. OperationType表中移除它们,并让应用程序根据BasicBasic-A列适当地启用这两个。
  2. 将Basic和Basic-A作为自己的正面标记放在OperationType表中,并让应用程序根据需要填充旧列和OperationType列。
  3. 正如Aaron Bertrand在评论中所说,这根本不是Bitmasking的问题。拥有一个将BusinessOperations.IDOperationType.ID相关联的众多表格可以更好地解决您的所有问题。