使用SQLite进行位掩码分组

Gil*_*vik 3 sqlite select group-by bitmask

我有一个sqlite表,当每个表有一个字段,我用来保存一些位掩码枚举.

我想执行一个查询,它将返回所有结果并将所有枚举分组到一个字段中:

服务:TEXT名称,INTEGER服务,INTEGER掩码

SELECT service,XXX FROM Services GROUP BY service
Run Code Online (Sandbox Code Playgroud)

基本上,我希望XXX是每个服务的所有掩码的位掩码OR(|)的结果.

数据:

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

'b1',2,1,
'b2',2,3,
'b3',2,2
Run Code Online (Sandbox Code Playgroud)

因此,我想获得以下行:

1,15 (1|2|4|8)
2,3 (1|3|2)
Run Code Online (Sandbox Code Playgroud)

谢谢

编辑: 在我原来的问题中,我忘了提到每个掩码不是一个位,但可以是多个位的掩码(我已经改变了第二个例子来反映).

ben*_*ado 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);
Run Code Online (Sandbox Code Playgroud)

然后在您的SQL中,您应该能够:

SELECT service,BITWISE_OR(mask) FROM Services GROUP BY service
Run Code Online (Sandbox Code Playgroud)

如果您正在使用PHP,您也可以从PHP定义自定义聚合函数.