How to select unique values ​​from multiple columns in Oracle SQL?

Basically, I have the following table:

ID | Amount
AA | 10
AA | 20
BB | 30
BB | 40
CC | 10
CC | 50
DD | 20
DD | 60
EE | 30
EE | 70

I need to get unique entries in each column, as in the following example:

ID | Amount
AA | 10
BB | 30
CC | 50
DD | 60
EE | 70

So far, the following snippet gives almost what I wanted, but first_value()can return some value that is not unique in the current column:

first_value(Amount) over (partition by ID)

Distinct also doesn't help as it returns unique strings and not its values

EDIT: The order of selection does not matter.

+4
source share
5 answers

This works for me, even with the problematic combinations mentioned by Demetrius. I do not know how quickly this is done for large volumes, but

with ids as (
  select id, row_number() over (order by id) as rn
  from data
  group by id
), amounts as (
  select amount, row_number() over (order by amount) as rn
  from data
  group by amount
)
select i.id, a.amount
from ids i
  join amounts a on i.rn = a.rn;

SQLFiddle , script:

create table data (id varchar(10), amount integer);

insert into data values ('AA',10);
insert into data values ('AA',20);
insert into data values ('BB',30);
insert into data values ('BB',40);
insert into data values ('CC',10);
insert into data values ('CC',50);
insert into data values ('DD',20);
insert into data values ('DD',60);
insert into data values ('EE',30);
insert into data values ('EE',70);

:

id | amount
---+-------
AA |     10
BB |     20
CC |     30
DD |     40
EE |     50
+2

row_number() :

select ID ,Amount
from (
   select ID ,Amount, row_number() over(partition by id order by 1) as rn
   from yourtable
     )
where rn = 1

, /, - /, , .

0

with : first - ID amount, ID amount, , ( ), 1 . , , ( , , , SQL).

with r (id, amount, lvl) as (select min(id), min(amount), 1
             from t
            union all
           select t.id, t.amount, r.lvl + 1
             from t, r
            where t.id > r.id and t.amount > r.amount)
select lvl, min(id), min(amount)
  from r
 group by lvl
 order by lvl

SQL Fiddle

0

, - :

WITH tx AS
     (  SELECT ROWNUM ROW_NUMBER,
               t.id,
               t.amount
          FROM test t
               INNER JOIN test t2
                   ON     t.id = t2.id
                      AND t.amount != t2.amount
      ORDER BY t.id)
SELECT tx1.id, tx1.amount
  FROM tx tx1
   LEFT JOIN tx tx2
       ON     tx1.id = tx2.id
          AND tx1.ROW_NUMBER > tx2.ROW_NUMBER
WHERE tx2.ROW_NUMBER IS NULL    
0

, ! :

select max(ID), mAmount from (
  select ID, max(Amount) mAmount from table group by ID
)
group by mAmount;
0

Source: https://habr.com/ru/post/1624941/


All Articles