tags:

views:

31

answers:

1

I have a table in mysql which stores (among other columns) a bitmask as a string, for example:

000100

I'd like to perform a query which will AND these fields together to provide a result that shows when any two mask positions are both true.

As an example, consider these three sample records:

id  name  mask
==  ====  ====
11  a     000100
12  a     000110
13  a     010000

This query is a self-join. I am looking for records where, for a given name, the same bitmask occurs twice or more.

In the above example, the only records that match this condition are 11 and 12 (the fourth bit is 1 in both cases).

The problem I am having is performing the AND on the mask. Since it is stored as a string, I am unsure how to get mysql to treat it as a binary value.

+2  A: 

You can use conv, eg.

select conv('1100', 2, 10) & conv('0110', 2, 10);

Re comment, it seems to work for me:

mysql> select conv('1001', 2, 10) & conv('0110', 2, 10) = 0;
+-----------------------------------------------+
| conv('1001', 2, 10) & conv('0110', 2, 10) = 0 |
+-----------------------------------------------+
|                                             1 |
+-----------------------------------------------+
1 row in set (0.00 sec)

mysql> select conv('1001', 2, 10) & conv('0111', 2, 10) = 0;
+-----------------------------------------------+
| conv('1001', 2, 10) & conv('0111', 2, 10) = 0 |
+-----------------------------------------------+
|                                             0 |
+-----------------------------------------------+
1 row in set (0.00 sec)
ar
Do you mean `select conv('1100', 2, 10) ` (a double ampersand instead of single)? Even with this correction, however, it still does not work as `select conv('1001', 2, 10) ` should evaluate to false, but it evaluates to true.
JYelton
Interesting, using just one ampersand works as per your edit. Apparently it is a bitwise `AND`, whereas the double ampersand is a logical `AND` - sorry I misread the documentation on that!
JYelton
@ar: you are indeed corrent, deleted my answer. Just the addendum: when comparing with a fixed bit one could use something like `b'0110'` instead of `conv('0110',2,10)`, but that would only work for literals, not for fieldnames.
Wrikken
@Wrikken: Correct, `conv` is needed for the column comparison. The `b'0'` notation is handy to know, though!
JYelton