关于sql中bit位的查询

postgresql:表中有个状态字段integet类型的,用于表示转换为bit(8)后的0、1状态。
例如1转换成00000001后,最后一位1表示某一个状态,0就表示没有某状态。

这8个状态分别用十进制的0,1,2,4...表示,已经在java中定义成常量了。

前台查询这个表时,传入多个状态,包含其中一个或者多个状态的数据都要查出来。

该怎么传数据、写SQL...

不知道说的清楚不?

如果前台传入一个3就是 00000011,表示把存在后两个状态其一或者全部的都查出来。但在sql里怎么进行判断呢?

后者前台不传入3而是其他结构的特定数据/?? 没想到好的办法,

传什么样的数据 ,还有SQL怎么写??? 哪位有经验的给个思路。后者给个sql。

thanks!!!
[b]问题补充:[/b]
我也试过这样开些动态sql但是,并不是所有参数都像3一样查询出1、2、3、
下面是一个列表,我没发现规律,
查询条件 符合条件的............................
1 0001 0001(1)
2 0010 0010(2)
3 0011 0001(1) 0010(2) 0011(3)
4 0100 0100(4)
5 0101 0001(1) 0100(4) 0101(5)
6 0110 0010 (2) 0100(4) 0110(6)
7 0111 0001(1) 0010(2) 0100(4) 0011(3) 0101(5) 0110(6) 0111(7)

8 1000 1000(8)
9 1001 0001(1) 1000(8) 1001(9)

直接: for(int i=1;i<=9;i++){

}

肯定是不对的。。。咋办??
[b]问题补充:[/b]
谢谢yourgame、playfish的回答。也给我思路。
playfish最后给出的结果还只是一个子集,没有组合结果。
我自己写了个方法,实验下好像没问题,但是还是感觉太麻烦,还是这东西本来就很麻烦?sql几个or下来估计很慢。。。
[code="java"]
static String returnZeros(int n){
StringBuffer bf = new StringBuffer();
for(int i=0;i<n;i++){
bf.append("0");
}
return bf.toString();
}

static List<String> getRelust(int state){
    List<String> list = new ArrayList<String>();//存放转化后的结果
    List<Integer> indexs = new ArrayList<Integer>();//存放二进制字符串转换成char[]后是1的数组下标
    String stateStr = Integer.toBinaryString(state);//将状态转换成二进制字符串
    stateStr = returnZeros(8-stateStr.length())+stateStr;//不够8位的补齐8位
    char[] stateArray = stateStr.toCharArray();
    for(int i=0;i<stateArray.length;i++){
        if(stateArray[i]=='1'){
            indexs.add(i);
        }
    }
    if (indexs.size()==1 || indexs.size()==8) {
        list.add(stateStr);
    }else{
        list.add(stateStr);
        for(int j=0;j<indexs.size();j++){
            list.add(returnZeros(indexs.get(j))+"1"+returnZeros(8-indexs.get(j)-1));
            for(int k=j+1;k<indexs.size();k++){
                list.add(returnZeros(indexs.get(j))+"1"+
                        returnZeros(indexs.get(k)-indexs.get(j)-1)+"1"+
                        returnZeros(8-indexs.get(k)-1));
            }
        }
    }
    return list;
}[/code]

哦 ,是个10进制与2进制转换问题,这个方法在做权限控制的时候很常见.

你可以参考下:

[url]http://ajax.cnrui.cn/article/52/55/2006/20061116893.shtml[/url]

只要将上面的代码做一点改变就行:

[code="java"] public static void main(String[] args) {

    int a = 5;
    String s = Integer.toBinaryString(a);

    String sql = "select * from t where s="+s;
    for(int i=0;i<s.length();i++){
        char c = s.charAt(i);           
        if(c=='1'){
            int t = (int)Math.pow(2, i);
            sql += " or s="+Integer.toBinaryString(t)+" ";  
        }
    }
    System.out.println(sql);
}[/code]

虽然丑陋,不过你仔细看看就会明白其中的原理.你的规律是将10进制转换成2进制的加减,比如 9 = 2^3 + 2^0 ,原理就是这样.

你在查询的时候,先计算除状态对应的bit(8) 或者整型的状态,到数据库中你可以用like或者完全相等

select state from table where state like '%value%'

或者
select state from table where state = value;

建议在数据库中用整型来表示状态,Null表示无状态,0,1,2,3,4,5分别表示其他状态
前台查询直接传值,不要计算成其他,这样放别得多,也便于理解.不然每次还要去计算一下.

bit的这个用法,感觉很像一个权限控制算法中的做法.用2进制位来表示权限大小.

[quote]如果前台传入一个3就是 00000011,表示把存在后两个状态其一或者全部的都查出来[/quote]

这个的意思是不是要查询出 00000001 00000010 00000011这3种状态?

如果是这样的话,你只需要将10进制转换成2进制,然后一个循环来生成sql条件.

[code="java"]
public static void main(String[] args) {

    String sql = "select * from t where ";

    int a = 3;
    for(int i=1;i<=3;i++){
        String t = i==1?"":"or ";       //第一个不需要or
        sql += t+"s="+Integer.toBinaryString(i)+" ";    //十进制转化为2进制字符串
    }
    System.out.println(sql);
}

[/code]

最后生成的代码如:

[code="java"]select * from t where s=1 or s=10 or s=11 [/code]

因为你说这个字段是integet类型的,所以这样应该可以比较出大小.前面多少个0都不会有影响吧.

如果实在是要长度都一样的话,那你就在Integer.toBinaryString(i)这加个判断,在前面补几个0就行了.