是否可以执行按位组功能?

nic*_*ckf 18 mysql sql oracle group-by aggregate-functions

我在一个包含按位标志的表中有一个字段.让我们说为了示例,有三个标志:4 => read, 2 => write, 1 => execute表格如下所示*:

  user_id  |  file  |  permissions
-----------+--------+---------------
        1  |  a.txt |  6    ( <-- 6 = 4 + 2 = read + write)
        1  |  b.txt |  4    ( <-- 4 = 4 = read)
        2  |  a.txt |  4
        2  |  c.exe |  1    ( <-- 1 = execute)
Run Code Online (Sandbox Code Playgroud)

我有兴趣找到在任何记录上设置了特定标志(例如:写入)的所有用户.要在一个查询中执行此操作,我认为如果您将所有用户的权限合并在一起,您将获得一个值,即其权限的"总和":

  user_id  |  all_perms
-----------+-------------
        1  |  6        (<-- 6 | 4 = 6)
        2  |  5        (<-- 4 | 1 = 5)
Run Code Online (Sandbox Code Playgroud)

*我的实际表格与文件或文件权限无关,只是一个例子

有没有办法在一个声明中执行此操作?我看到它的方式,它与GROUP BY的普通聚合函数非常相似:

SELECT user_id, SUM(permissions) as all_perms
FROM permissions
GROUP BY user_id
Run Code Online (Sandbox Code Playgroud)

......但很明显,有些神奇的"按位或"函数代替SUM.有人知道这样的事吗?

(而对于奖励积分,它在甲骨文中有效吗?)

man*_*nji 19

MySQL的:

SELECT user_id, BIT_OR(permissions) as all_perms
FROM permissions
GROUP BY user_id
Run Code Online (Sandbox Code Playgroud)

  • 像往常一样,MySQL踢了oracle的屁股. (2认同)

nic*_*ckf 8

啊,另外一个问题,我在询问后5分钟找到答案...接受的答案将转到MySQL实现虽然...

正如我在Radino的博客上发现的,这是如何使用Oracle

你创建一个对象......

CREATE OR REPLACE TYPE bitor_impl AS OBJECT
(
  bitor NUMBER,

  STATIC FUNCTION ODCIAggregateInitialize(ctx IN OUT bitor_impl) RETURN NUMBER,

  MEMBER FUNCTION ODCIAggregateIterate(SELF  IN OUT bitor_impl,
                                       VALUE IN NUMBER) RETURN NUMBER,

  MEMBER FUNCTION ODCIAggregateMerge(SELF IN OUT bitor_impl,
                                     ctx2 IN bitor_impl) RETURN NUMBER,

  MEMBER FUNCTION ODCIAggregateTerminate(SELF        IN OUT bitor_impl,
                                         returnvalue OUT NUMBER,
                                         flags       IN NUMBER) RETURN NUMBER
)
/

CREATE OR REPLACE TYPE BODY bitor_impl IS
  STATIC FUNCTION ODCIAggregateInitialize(ctx IN OUT bitor_impl) RETURN NUMBER IS
  BEGIN
    ctx := bitor_impl(0);
    RETURN ODCIConst.Success;
  END ODCIAggregateInitialize;

  MEMBER FUNCTION ODCIAggregateIterate(SELF  IN OUT bitor_impl,
                                       VALUE IN NUMBER) RETURN NUMBER IS
  BEGIN
    SELF.bitor := SELF.bitor + VALUE - bitand(SELF.bitor, VALUE);
    RETURN ODCIConst.Success;
  END ODCIAggregateIterate;

  MEMBER FUNCTION ODCIAggregateMerge(SELF IN OUT bitor_impl,
                                     ctx2 IN bitor_impl) RETURN NUMBER IS
  BEGIN
    SELF.bitor := SELF.bitor + ctx2.bitor - bitand(SELF.bitor, ctx2.bitor);
    RETURN ODCIConst.Success;
  END ODCIAggregateMerge;

  MEMBER FUNCTION ODCIAggregateTerminate(SELF        IN OUT bitor_impl,
                                         returnvalue OUT NUMBER,
                                         flags       IN NUMBER) RETURN NUMBER IS
  BEGIN
    returnvalue := SELF.bitor;
    RETURN ODCIConst.Success;
  END ODCIAggregateTerminate;
END;
/
Run Code Online (Sandbox Code Playgroud)

...然后定义自己的聚合函数

CREATE OR REPLACE FUNCTION bitoragg(x IN NUMBER) RETURN NUMBER
PARALLEL_ENABLE
AGGREGATE USING bitor_impl;
/
Run Code Online (Sandbox Code Playgroud)

用法:

SELECT user_id, bitoragg(permissions) FROM perms GROUP BY user_id
Run Code Online (Sandbox Code Playgroud)