我希望在BITAND
中使用JOIN
来对记录进行分类。
此查询正确地将器官分组:
WITH
data AS (
select 2 bits, 'LUNG [2]' organs from dual
union all
select 18 bits, 'LUNG [2]; KIDNEY [16]' organs from dual
union all
select 64 bits, 'HEART [64]' organs from dual
union all
select 66 bits, 'LUNG [2]; HEART [64]' organs from dual
)
select *
,case when BITAND(bits,2)=2 OR BITAND(bits,66)=66 then 'Y' end LUNG_YN
,case when BITAND(bits,16)=16 or BITAND(bits,4)=4 then 'Y' end KIDNEY_YN
,case when BITAND(bits,64)=64 AND not BITAND(bits,2)=2 then 'Y' end HEART_YN
from data
结果:
BITS ORGANS LUNG_YN KIDNEY_YN HEART_YN
2 LUNG [2] Y
18 LUNG [2]; KIDNEY [16] Y Y
64 HEART [64] Y
66 LUNG [2]; HEART [64] Y*
(*肺/心脏组合被企业视为'肺';不要问)
但是,我还需要将每个器官记录放入多个桶中:
BITS ORGANS BUCKET
2 LUNG [2] LUNG [2]
18 LUNG [2]; KIDNEY [16] LUNG [2]
18 LUNG [2]; KIDNEY [16] KIDNEY [16]
64 HEART [64] HEART [64]
66 LUNG [2]; HEART [64] LUNG [2]
为了生成这个,我正在使用:
-- referencing earlier data table
p as (
select 2 BITS, 'LUNG [2]' BUCKET from dual
union all
select 16 BITS, 'KIDNEY [16]' BUCKET from dual
union all
select 64 BITS, 'HEART [64]' BUCKET from dual
)
select data.*
,p.*
from data
inner join p on BITAND(data.bits,p.bits)=p.bits
order by data.bits, p.bits
不幸的是,这导致了额外的分配(最后一行):
BITS ORGANS BUCKET
2 LUNG [2] LUNG [2]
18 LUNG [2]; KIDNEY [16] LUNG [2]
18 LUNG [2]; KIDNEY [16] KIDNEY [16]
64 HEART [64] HEART [64]
66 LUNG [2]; HEART [64] LUNG [2]
66 LUNG [2]; HEART [64] HEART [64] (*erroneous*)
**编辑**
我限制器官组合以简化问题。因此,我不能简单地列出p
中的所有按位组合 - 它确实需要“更聪明”。
** /编辑**
有没有办法构建BITAND
中的JOIN
(或p
中的值)以使查询以所需方式运行?
答案 0 :(得分:1)
明确询问该商家如何映射BUCKET
答案将是这样的
create table map_bucket as
WITH map_bucket AS (
select 2 bits, 'LUNG [2]' BUCKET from dual
union all
select 18 bits, 'LUNG [2]' BUCKET from dual
union all
select 18 bits, 'KIDNEY [16]' BUCKET from dual
union all
select 64 bits, 'HEART [64]' BUCKET from dual
union all
select 66 bits, 'LUNG [2]' BUCKET from dual
)
select * from map_bucket
;
在重新生成查询中使用此映射表:
WITH data AS (
select 2 bits, 'LUNG [2]' organs from dual
union all
select 18 bits, 'LUNG [2]; KIDNEY [16]' organs from dual
union all
select 64 bits, 'HEART [64]' organs from dual
union all
select 66 bits, 'LUNG [2]; HEART [64]' organs from dual
)
select data.*,
p.*
from data
inner join map_bucket p on data.bits=p.bits
order by data.bits, p.bits
;
按预期结果:
BITS ORGANS BITS BUCKET
---------- --------------------- ---------- -----------
2 LUNG [2] 2 LUNG [2]
18 LUNG [2]; KIDNEY [16] 18 LUNG [2]
18 LUNG [2]; KIDNEY [16] 18 KIDNEY [16]
64 HEART [64] 64 HEART [64]
66 LUNG [2]; HEART [64] 66 LUNG [2]
或者,如果您只需要消除少数例外,可以在连接条件中简单地添加它们:
select data.*
,p.*
from data
inner join p on BITAND(data.bits,p.bits)=p.bits
and /* suppress exception here - lung & hearts count as lung only */
(data.bits != 66 or p.bits = 2)
order by data.bits, p.bits
;
答案 1 :(得分:0)
找到了解决方案。
此查询:
select data.*
,p.*
from data
inner join p ON
(bitand(data.bits,2)=p.bits OR bitand(data.bits,66)=p.bits) OR
(bitand(data.bits,16)=p.bits)
order by tt.bits, p.bits
产生所需的结果:
BITS ORGANS BUCKET
2 LUNG [2] LUNG [2]
18 LUNG [2]; KIDNEY [16] LUNG [2]
18 LUNG [2]; KIDNEY [16] KIDNEY [16]
64 HEART [64] HEART [64]
66 LUNG [2]; HEART [64] LUNG [2]