Oracle 中每列的最佳价值
Best Value per Each Column in Oracle
我有一个特殊的问题想要解决。假设我有一个具有以下结构和值的 table
Col1 Col2 Col3 Col4
A 3 S #
A 3 S #
A 3 X #
A 3 X #
A 3 X @
A 3 X @
A 5 X @
A 5 X @
A 5 S #
A 5 S #
如果我们在上面的 column2 中看到 3 的值重复了最大次数,col3 重复了 X 次最大次数而 Col4 有 #.
所以我想使用 SQL 形成一行输出,如下所示。
Col1 Col2 Col3 Col4
A 3 X #
如果语句是SQL而不是PLSQL
就好了
看看这是否有帮助;示例数据来自第 1 - 14 行;您需要的查询从第 16 行开始。
SQL> with
2 -- sample data
3 test (col1, col2, col3, col4) as
4 (select 'a', 3, 's', '#' from dual union all
5 select 'a', 3, 's', '#' from dual union all
6 select 'a', 3, 'x', '#' from dual union all
7 select 'a', 3, 'x', '#' from dual union all
8 select 'a', 3, 'x', '@' from dual union all
9 select 'a', 3, 'x', '@' from dual union all
10 select 'a', 5, 'x', '@' from dual union all
11 select 'a', 5, 'x', '@' from dual union all
12 select 'a', 5, 's', '#' from dual union all
13 select 'a', 5, 's', '#' from dual
14 )
15 -- query you need
16 select distinct
17 t.col1,
18 a.col2,
19 b.col3,
20 c.col4
21 from test t cross join
22 (select col2,
23 rank() over (order by count(*) desc) rnk2
24 from test
25 group by col2
26 ) a
27 cross join
28 (select col3,
29 rank() over (order by count(*) desc) rnk3
30 from test
31 group by col3
32 ) b
33 cross join
34 (select col4,
35 rank() over (order by count(*) desc) rnk4
36 from test
37 group by col4
38 ) c
39 where a.rnk2 = 1
40 and b.rnk3 = 1
41 and c.rnk4 = 1
42 /
C COL2 C C
- ---------- - -
a 3 x #
SQL>
您可以使用下面的方法来获取需求
with data as (select 'A' Col1, 3 Col2 , 'S' Col3, '#' Col4 from dual UNION all
select 'A' , 3 , 'S', '#' from dual UNION all
select 'A' , 3 , 'X', '#' from dual UNION all
select 'A' , 3 , 'X', '#' from dual UNION all
select 'A' , 3 , 'X', '@' from dual UNION all
select 'A' , 3 , 'X', '@' from dual UNION all
select 'A' , 5 , 'X', '@' from dual UNION all
select 'A' , 5 , 'X', '@' from dual UNION all
select 'A' , 5 , 'S', '#' from dual UNION all
select 'A' , 5 , 'S', '#' from dual),
data1 as (
select
Col1,
count(Col2) over (partition by col1,col2 order by col2) cnt_col2,
Col2,
count(Col3) over (partition by col1,col3 order by col3) cnt_col3,
Col3,
count(Col4) over (partition by col1,col4 order by col4) cnt_col4,
Col4
from data
),data2 as
(
select col1,col2,col3,col4,max(cnt_col2)||max(cnt_col3)||max(cnt_col4) Max_cnt
from data1
group by Col1, Col2 , Col3, Col4)
select Col1, Col2 , Col3, Col4 from data2
where (max_cnt,col1) in (select max(max_cnt),
col1 from data2 group by col1);
从 a_horse_with_no_name 的回答中获得帮助,您可以尝试以下是否可以解决您的性能问题
SELECT DISTINCT d.*
FROM data d
WHERE ( col1, col2 ) IN (SELECT col1,
Stats_mode(col2) col2
FROM data
GROUP BY col1)
AND ( col1, col2, col3 ) IN (SELECT col1,
col2,
Stats_mode(col3) col3
FROM data
GROUP BY col1,
col2)
AND ( col1, col2, col3, col4 ) IN (SELECT col1,
col2,
col3,
Stats_mode(col4) col4
FROM data
GROUP BY col1,
col2,
col3)
您可以为此使用 stats_mode()
函数:
select STATS_MODE(col1) as col1,
STATS_MODE(col2) as col2,
STATS_MODE(col3) as col3,
STATS_MODE(col4) as col4
from the_table
;
我有一个特殊的问题想要解决。假设我有一个具有以下结构和值的 table
Col1 Col2 Col3 Col4
A 3 S #
A 3 S #
A 3 X #
A 3 X #
A 3 X @
A 3 X @
A 5 X @
A 5 X @
A 5 S #
A 5 S #
如果我们在上面的 column2 中看到 3 的值重复了最大次数,col3 重复了 X 次最大次数而 Col4 有 #.
所以我想使用 SQL 形成一行输出,如下所示。
Col1 Col2 Col3 Col4
A 3 X #
如果语句是SQL而不是PLSQL
就好了看看这是否有帮助;示例数据来自第 1 - 14 行;您需要的查询从第 16 行开始。
SQL> with
2 -- sample data
3 test (col1, col2, col3, col4) as
4 (select 'a', 3, 's', '#' from dual union all
5 select 'a', 3, 's', '#' from dual union all
6 select 'a', 3, 'x', '#' from dual union all
7 select 'a', 3, 'x', '#' from dual union all
8 select 'a', 3, 'x', '@' from dual union all
9 select 'a', 3, 'x', '@' from dual union all
10 select 'a', 5, 'x', '@' from dual union all
11 select 'a', 5, 'x', '@' from dual union all
12 select 'a', 5, 's', '#' from dual union all
13 select 'a', 5, 's', '#' from dual
14 )
15 -- query you need
16 select distinct
17 t.col1,
18 a.col2,
19 b.col3,
20 c.col4
21 from test t cross join
22 (select col2,
23 rank() over (order by count(*) desc) rnk2
24 from test
25 group by col2
26 ) a
27 cross join
28 (select col3,
29 rank() over (order by count(*) desc) rnk3
30 from test
31 group by col3
32 ) b
33 cross join
34 (select col4,
35 rank() over (order by count(*) desc) rnk4
36 from test
37 group by col4
38 ) c
39 where a.rnk2 = 1
40 and b.rnk3 = 1
41 and c.rnk4 = 1
42 /
C COL2 C C
- ---------- - -
a 3 x #
SQL>
您可以使用下面的方法来获取需求
with data as (select 'A' Col1, 3 Col2 , 'S' Col3, '#' Col4 from dual UNION all
select 'A' , 3 , 'S', '#' from dual UNION all
select 'A' , 3 , 'X', '#' from dual UNION all
select 'A' , 3 , 'X', '#' from dual UNION all
select 'A' , 3 , 'X', '@' from dual UNION all
select 'A' , 3 , 'X', '@' from dual UNION all
select 'A' , 5 , 'X', '@' from dual UNION all
select 'A' , 5 , 'X', '@' from dual UNION all
select 'A' , 5 , 'S', '#' from dual UNION all
select 'A' , 5 , 'S', '#' from dual),
data1 as (
select
Col1,
count(Col2) over (partition by col1,col2 order by col2) cnt_col2,
Col2,
count(Col3) over (partition by col1,col3 order by col3) cnt_col3,
Col3,
count(Col4) over (partition by col1,col4 order by col4) cnt_col4,
Col4
from data
),data2 as
(
select col1,col2,col3,col4,max(cnt_col2)||max(cnt_col3)||max(cnt_col4) Max_cnt
from data1
group by Col1, Col2 , Col3, Col4)
select Col1, Col2 , Col3, Col4 from data2
where (max_cnt,col1) in (select max(max_cnt),
col1 from data2 group by col1);
从 a_horse_with_no_name 的回答中获得帮助,您可以尝试以下是否可以解决您的性能问题
SELECT DISTINCT d.*
FROM data d
WHERE ( col1, col2 ) IN (SELECT col1,
Stats_mode(col2) col2
FROM data
GROUP BY col1)
AND ( col1, col2, col3 ) IN (SELECT col1,
col2,
Stats_mode(col3) col3
FROM data
GROUP BY col1,
col2)
AND ( col1, col2, col3, col4 ) IN (SELECT col1,
col2,
col3,
Stats_mode(col4) col4
FROM data
GROUP BY col1,
col2,
col3)
您可以为此使用 stats_mode()
函数:
select STATS_MODE(col1) as col1,
STATS_MODE(col2) as col2,
STATS_MODE(col3) as col3,
STATS_MODE(col4) as col4
from the_table
;