我在表中有一个包含按位标志的字段。让我们说,例如,有三个标志: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)
我有兴趣找到在任何记录上设置了特定标志(例如:写入)的所有用户。要在一个查询中执行此操作,我认为如果您将所有用户的权限合并在一起,您将获得一个值,即其权限的“总和”:
user_id | all_perms
-----------+-------------
1 | 6 (<-- 6 | 4 = 6)
2 | 5 (<-- 4 | 1 = 5)
*
我的实际表与文件或文件权限无关,只是一个例子
有没有办法在一个声明中执行此操作?我看到它的方式,它与GROUP BY的正常聚合函数非常相似:
SELECT user_id, SUM(permissions) as all_perms
FROM permissions
GROUP BY user_id
...但显然,有些神奇的“按位或”功能代替SUM。任何人都知道这样的事情吗?
(对于奖励积分,它在甲骨文中有效吗?)
答案 0 :(得分:18)
MySQL的:
SELECT user_id, BIT_OR(permissions) as all_perms
FROM permissions
GROUP BY user_id
答案 1 :(得分:7)
啊,另外一个问题,我在询问后5分钟找到答案...接受的答案将转到MySQL实现,但是......
上发现了如何使用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;
/
...然后define your own aggregate function
CREATE OR REPLACE FUNCTION bitoragg(x IN NUMBER) RETURN NUMBER
PARALLEL_ENABLE
AGGREGATE USING bitor_impl;
/
用法:
SELECT user_id, bitoragg(permissions) FROM perms GROUP BY user_id
答案 2 :(得分:2)
你可以做一点点或用......
FUNCTION BITOR(x IN NUMBER, y IN NUMBER)
RETURN NUMBER
AS
BEGIN
RETURN x + y - BITAND(x,y);
END;
答案 3 :(得分:1)
您需要知道可能的权限组件(1,2和4)apriori(因此难以维护),但这很简单并且可以工作:
SELECT user_id,
MAX(BITAND(permissions, 1)) +
MAX(BITAND(permissions, 2)) +
MAX(BITAND(permissions, 4)) all_perms
FROM permissions
GROUP BY user_id
答案 4 :(得分:0)
我有兴趣找到所有用户 有一个特定的标志集(例如:写) 在任何记录上
简单
有什么问题SELECT DISTINCT User_ID
FROM Permissions
WHERE permissions & 2 = 2