我有一张桌子,里面装满了各种各样的“面具”,如下所示:
Type Mask1 Mask2 Mask3
0 fff fff ff
1 aff fff ff
2 aff fff 92
3 001 fff 00
基本上我想查询数据库并查看特定查询是否匹配,例如 a00-111-12 。
任何地方都有 f < / b>(这都是十六进制)我想说有一个匹配。
所以我取值 a00-111-12 它应该与行0和1匹配但不匹配2和3,因为在行0中,所有 f < / b>出现,因此与它们的值和将导致相同的值。但是,AND-ing不起作用,因为如果使用第2行测试,Mask3列值92和12与12结果会产生12,但我不希望该行匹配。
我觉得这个问题很难解决,用一些MySQL查询可能无法实现,但我想避免将整个表导入PHP,然后从那里找到正确的行。
查询的想法是:
SELECT * FROM TABLE WHERE Mask1 = a00 AND Mask2 = 111 AND ...
但是,需要对Mask1,2,3或发送到查询的值进行某些操作。
最终目标是从匹配的行中获取类型。如果您需要更多信息,请询问。
答案 0 :(得分: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))
)
这种方法的工作方式是比较各个十六进制数字,方法是使用z1
,z2
和z2
进行按位AND,分别得到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.
对z1
,z2
和z3
(即0x00f
,0x0f0
和0xf00
)中的每一项重复测试结果使用和条件,您可以检查掩码的所有3个十六进制数字是f
还是完全是测试值。
然后对Mask2和Mask3重复这一过程(但只有z1,z2,因为Mask3是2位数)。
通过对子掩码表使用内连接,结果将只包括掩码条件为真的表中的值。
更新 - 您可能希望执行select distinct
而不只是select
,就像两个掩码与表格中的一行匹配一样,然后会返回2个结果。
答案 1 :(得分: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
不匹配,尽管我希望如此。还在努力......