我需要一个查询来省略两个记录中存在数字16的组,并且这些组存在于组内的不同属性中。基本上,如果我们在不同记录的属性中有一个16,那么我们知道这些组的帐户是什么,并且不需要对它们进行进一步的分析。我们希望保留结果,其中16只出现在任一属性中的一个记录中,16出现在两者中,并且记录中包含空值但没有16个记录在不同属性中。
以下是一个例子:
---------------------------------------------
| groupid | category | test_results |
---------------------------------------------
| 001 | red13tall | |
| 001 | | blue16small |
| 002 | green16small| |
| 002 | | blue16small |
| 003 | yellow3tall | |
| 003 | | green2giant |
| 004 | orange16tall | |
| 004 | | blue16tall |
| 005 | red16short | |
| 005 | green12bald | orange14tall |
| 006 | blue3short | red16big |
| 006 | green16flat | |
---------------------------------------------
这是我们正在寻找的结果:
---------------------------------------------
| groupid | category | test_results |
---------------------------------------------
| 001 | red13tall | |
| 001 | | blue16small |
| 003 | yellow3tall | |
| 003 | | green2giant |
| 005 | red16short | |
| 005 | green12bald | orange14tall |
------------------------------------------
答案 0 :(得分:1)
假设您的表名为your_table
且主键为id
,那么
SELECT t3.groupid, t3.category, t3.test_results
FROM your_table t3
WHERE t3.groupid NOT IN (
SELECT t1.groupid
FROM your_table t1, your_table t2
WHERE t1.id <> t2.id
AND t1.groupid = t2.groupid
AND t1.category LIKE '%16%'
AND t2.test_results LIKE '%16%'
)
注意,这假设您正在寻找16
出现在2个不同列中的两个不同行中。如果您不在乎它们是否出现在同一行中,则可以删除t1.id <> t2.id
条件。
答案 1 :(得分:1)
您需要以某种方式进行条件计数。如果使用分析函数,则可以避免连接,这通常会影响性能。
对于下面的解决方案,我按字面解释了你的单词:每组只有两行,如果满足所有三个条件,则排除一组:两行至少有16行(category
或{{} 1}}); 16 test_results
出现至少一次;和{16}出现在category
至少一次。
如果您不需要至少有一次16的组的每一行上的条件,则可以非常轻松地修改查询(删除对test_results
的所有引用)。
r_ct
<强>输出强>:
with
test_data ( groupid, category, test_results ) as (
select '001', 'red13tall' , null from dual union all
select '001', null , 'blue16small' from dual union all
select '002', 'green16small', null from dual union all
select '002', null , 'blue16small' from dual union all
select '003', 'yellow3tall' , null from dual union all
select '003', null , 'green2giant' from dual union all
select '004', 'orange16tall', null from dual union all
select '004', null , 'blue16tall' from dual union all
select '005', 'red16short' , null from dual union all
select '005', 'green12bald' , 'orange14tall' from dual union all
select '006', 'blue3short' , 'red16big' from dual union all
select '006', 'green16flat' , null from dual
)
-- end of test data (not part of solution); SQL query begins below this line
select groupid, category, test_results
from (
select groupid, category, test_results,
count(case when category like '%16%' then 1
when test_results like '%16%' then 1 end)
over (partition by groupid) as r_ct,
count(case when category like '%16%' then 1 end)
over (partition by groupid) as c_ct,
count(case when test_results like '%16%' then 1 end)
over (partition by groupid) as t_ct
from test_data
)
where r_ct < 2 or c_ct = 0 or t_ct = 0
order by groupid -- if needed
;