0

我有一张桌子,上面摆满了各种“面具”,例如:

Type    Mask1    Mask2    Mask3
0       fff      fff      ff
1       aff      fff      ff
2       aff      fff      92 
3       001      fff      00   

基本上我想查询数据库并查看特定查询是否匹配,例如a00-111-12

任何有f的地方(这都是十六进制的)我想说有一个匹配。

所以我取值a00-111-12它应该与第 0 行和第 1 行匹配,但不与第 2 行和第 3 行匹配,因为在第 0 行中,所有f都出现了,因此与它们进行与运算的值将产生相同的值。但是,AND-ing 不起作用,因为如果使用第 2 行进行测试,Mask3 列值 92 与 12 的结果为 12,但是我不希望该行匹配。

我发现这是一个很难问的问题,可能无法使用一些 MySQL 查询,但我想避免将整个表导入 PHP,然后从那里找到正确的行。

查询的想法是:


    SELECT * FROM TABLE WHERE Mask1 = a00 AND Mask2 = 111 AND ...
    
但是,需要对 Mask1、2、3 或发送到查询的值进行一些操作。

最终目标是从匹配的行中获取类型。如果您需要更多信息,请询问。

4

2 回答 2

0

创建一个子掩码表以使您的工作更轻松,添加一行

 z1 :  z2  : z3
0xf : 0xf0 : 0xf00

然后使用以下查询

   Select 
           t.*
   from Table t 
   inner join submasks s
     on (
         ((t.Mask1 & s.z1) = s.z1 || (t.Mask1 & s.z1) = (a00 & s.z1)) &&
         ((t.Mask1 & s.z2) = s.z2 || (t.Mask1 & s.z2) = (a00 & s.z2)) &&
         ((t.Mask1 & s.z2) = s.z2 || (t.Mask1 & s.z2) = (a00 & s.z2)) &&
         ((t.Mask2 & s.z1) = s.z1 || (t.Mask2 & s.z1) = (111 & s.z1)) &&
         ((t.Mask2 & s.z2) = s.z2 || (t.Mask2 & s.z2) = (111 & s.z2)) &&
         ((t.Mask2 & s.z2) = s.z2 || (t.Mask2 & s.z2) = (111 & s.z2)) &&
         ((t.Mask3 & s.z1) = s.z1 || (t.Mask3 & s.z1) = (12 & s.z1)) &&
         ((t.Mask3 & s.z2) = s.z2 || (t.Mask3 & s.z2) = (12 & s.z2))
   )

其工作方式是通过与 执行按位与比较单个十六进制数字z1z2z2分别获得 3 个数字中的每一个。

所以

  • <any value> & z1将除最后一位之外的所有十六进制数字设置为 0,即0x123变为0x003
  • <any value> & z2将除倒数第二个之外的所有十六进制数字设置为 0,即0x123变为0x020
  • <any value> & z3将除倒数第三个之外的所有十六进制数字设置为 0,即0x123变为0x100

使用此过滤器,每个数字的测试可以构建为

((mask & filter) = filter)          // is the digit f
||                                  // OR
((mask & filter) = (test & filter)) // is the digit the same.

对 , 和中的每一个重复测试z1z2并且z3(即0x00f,0x0f00xf00)将结果与 and 条件结合起来,您可以检查掩码的所有 3 个十六进制数字是否为f测试值或完全为测试值。

然后对 Mask2 和 Mask3 重复此操作(但只有 z1,z2 因为 Mask3 是 2 位数字)。

通过对子掩码表使用内连接,结果将仅包括掩码条件为真的表中的值。

更新- 您可能想要执行select distinct而不是就像select两个掩码匹配表中的单行,然后将返回 2 个结果。

于 2013-06-27T17:37:47.880 回答
0

不知道我是否很好地解释了我的问题,但我最终得出这样的结论:这是最有效的:

val1 = 0xa00
val2 = 0x111
val3 = 0x12

SELECT * FROM TABLE WHERE 
((Mask1 | val1)=val1 OR (Mask1 | val1)=0xfff) AND
((Mask1 | val2)=val2 OR (Mask1 | val2)=0xfff) AND
((Mask1 | val3)=val3 OR (Mask1 | val2)=0xfff);

唯一的问题是,虽然我希望它val1=a00不匹配。Mask1=aff还在努力...

于 2013-06-28T12:56:58.063 回答