这个答案很荒谬,但我相信它的确有窍门!这可能是大型数据集,而慢...
with selector as
(select rownum-1 as setnum
from dual
connect by level <= power(2,(select count(*) from my_table))
), /* This generates the integers 0..(2^n)-1 where n is number of rows in table */
data as
(select c1, c2, row_number() over (order by c1, c2) as rn
from my_table
), /* This assigns each row in the table a row number 1..n */
cj as
(select setnum, c1, c2
from selector cross join data
where bitand(setnum, power(2,rn-1)) = power(2,rn-1)
), /* This generates all the possible sets of 1-n rows.
The rows in the set are determined by the bits of the setnum value
e.g. setnum 5 (101 in binary) contains rows 1 and 4 */
set_sizes as
(select setnum, count(*) cnt from cj
group by setnum
having count(distinct c1) = (select count(distinct c1) from my_table)
and count(distinct c2) = (select count(distinct c2) from my_table)
), /* This determines the number of rows in each set AND excludes sets that
don't include all the c1 and c2 values */
one_set as
(select min(setnum) minsetnum from set_sizes
where cnt = (select min(cnt) from set_sizes)
) /* This selects one of the sets that has the smallest number of rows */
select c1, c2 from cj
where setnum = (select minsetnum from one_set)
order by 1
它这样做是:
- 产生从表
- 过滤掉那些不包含所有C1行的所有可能集合价值观和所有C2值
- 发现这些
- 最小的套任意选择这些最小的集合中的一个,并返回其数据
如果任何人都可以为我的with-clause子查询建议更好(更有意义)的名字,请做!
它会一直如此吗?每个C1都具有C2中的所有值和相反? – Yossi
如果你要保留a1-b1的组合,或者它可以是a2-b1,这有什么关系? – Veljko89
@Yossi,不会有另一排在那里a4 |例如,没有其他值的c4。 – Cantillon