3

各テーブルにビットマスク列挙型を保持するために使用するフィールドがある場合、sqliteテーブルがあります。

すべての結果を返し、すべての列挙型を1つのフィールドにグループ化するクエリを実行したいと思います。

サービス:TEXT名、INTEGERサービス、INTEGERマスク

SELECT service,XXX FROM Services GROUP BY service

基本的に、XXXは、そのサービスごとのすべてのマスクのビットマスクOR(|)の結果になります。

データ:

'a1',1,1
'a2',1,2,
'a3',1,4,
'a4',1,8,

'b1',2,1,
'b2',2,3,
'b3',2,2

その結果、次の行を取得したいと思います。

1,15 (1|2|4|8)
2,3 (1|3|2)

ありがとう

編集: 私の元の質問では、各マスクが単一のビットではなく、複数のビットのマスクである可能性があることを言及するのを忘れました(それを反映するために2番目の例を変更しました)。

4

2 に答える 2

6

SQLite はカスタム集計関数をサポートしています。設定によっては、カスタム関数を登録して、これを非常に簡単に行うことができます。C API の使用:

void bitwise_or_step(sqlite3_context *context, int argc, sqlite3_value** argv)
{
    int *buffer = (int *)sqlite3_aggregate_context(context, sizeof(int));
    int x = sqlite3_value_int(argv[0]);
    *buffer |= x;
}

void bitwise_or_final(sqlite3_context *context)
{
    int *buffer = (int *)sqlite3_aggregate_context(context, sizeof(int));
    sqlite3_result_int(context, *buffer);
}

sqlite3_create_function_v2(db, "BITWISE_OR", 1, SQLITE_ANY, NULL,
    NULL, bitwise_or_step, bitwise_or_final, NULL);

次に、SQL内で次のことができるはずです。

SELECT service,BITWISE_OR(mask) FROM Services GROUP BY service

PHP を使用している場合は、PHP からカスタム集計関数を定義することもできます。

于 2012-01-30T23:57:09.327 に答える
2

SQL での整数のビットマスク OR (|) 演算は、キーごとに一意の 2 の累乗値を合計する単純な問題です。

todd$ sqlite3 ex1
SQLite version 3.7.5
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> create table Services(Name varchar(100), Service int, mask int);
sqlite> insert into Services values("a1", 1, 1);
sqlite> insert into Services values("a2", 1, 2);
sqlite> insert into Services values("a3", 1, 4);
sqlite> insert into Services values("a4", 1, 8);
sqlite> insert into Services values("b1", 2, 1);
sqlite> insert into Services values("b2", 2, 3);
sqlite> insert into Services values("b3", 2, 2);
sqlite> select * from Services;
a1|1|1
a2|1|2
a3|1|4
a4|1|8
b1|2|1
b2|2|3
b3|2|2

EDIT:ビットマップドメインがわかっている場合は、値をビットアンドアンドでその部分に分割して合計することができます:

sqlite> select Service, max(mask&1) + max(mask&2) +  max(mask&4) + max(mask&8) from Services group by Service;
1|15
2|3
sqlite> 

ビットマップ マスクに格納しているすべての既知の 2 のべき乗に対してmax(mask& bit ) ロジックを拡張できます。

于 2012-01-27T15:56:51.580 に答える