Remove multiple entries for a column - sql

I need two columns A and B but of them A has repeated values and B has single unique values. I have to fetch only those values of A which has max(C) value. C is another column.

You can use ROW_NUMBER.
ROW_NUMBER
Returns the sequential number of a row within a partition of a result
set, starting at 1 for the first row in each partition.
PARTITION BY value_expression
Divides the result set produced by the
FROM clause into partitions to which the ROW_NUMBER function is
applied. value_expression specifies the column by which the result set
is partitioned. If PARTITION BY is not specified, the function treats
all rows of the query result set as a single group.
ORDER BY
The ORDER BY clause determines the sequence in which the rows are assigned their unique ROW_NUMBER within a specified
partition. It is required.
Sample of ROW_NUMBER in your case:
SELECT A, B
FROM
(
SELECT ROW_NUMBER() OVER(PARTITION BY A ORDER BY C DESC) AS RowNum, A, B, C
FROM TableName
)
WHERE RowNum = 1

Use Row_Number Analytic function to do this
select A,B
from
(
select row_number() over(partition by A order by C desc)rn,A,B,C
from yourtable
)
where RN=1

An alternative to #NoDisplayName's solution is to use keep dense_rank first/last:
with your_table as (select 1 a, 3 b, 10 c from dual union all
select 1 a, 2 b, 20 c from dual union all
select 1 a, 1 b, 30 c from dual union all
select 2 a, 4 b, 40 c from dual union all
select 2 a, 5 b, 60 c from dual union all
select 2 a, 3 b, 60 c from dual union all
select 3 a, 6 b, 70 c from dual union all
select 4 a, 2 b, 80 c from dual)
select a,
max(b) keep (dense_rank first order by c desc) b,
max(c) max_c
from your_table
group by a;
A B MAX_C
---------- ---------- ----------
1 1 30
2 5 60
3 6 70
4 2 80

Using the INTERSECT keyword get those rows which have maximum value of ColC for the ColA.
select ColA, ColB from
(
select ColA, ColB, max(colC) from Tabl
group by ColA, ColB
intersect
select ColA, ColB, ColC from Tabl
) as A

Related

How to get the record (by group) with max value? (Big Query)

Consider the following data
Column A
Column B
Column C
A
t
9
A
d
12
A
l
8
B
x
7
B
z
9
B
q
6
How do I extract the record with the max value in Col C for each value in Col A.
So the expected result would be...
Column A
Column B
Column C
A
d
12
B
z
9
Trying
select ColA, max(ColC) from table group by ColA
doesn't provide the value in ColB.
I'm sure there is a simple and elegant solution here, but it's escaping me....
Consider below approach
select * from your_table
qualify 1 = row_number() over(partition by colA order by colC desc)
if applied to sample data in y our question - output is
window function can be used here:
with tbl as (
Select "A" as colA, "t" as colB, 9 as colC
union all select "A","d", 12
union all select "A","dd", 12
union all select "A","l", 8
union all select "B","x", 7
union all select "B","z", 9
union all select "B","q", 6
)
select
colA,
max(colC),
any_Value(colB_max)
from (select *, first_value(colB) over (partition by colA order by colC desc) as colB_max from tbl )
group by 1
I added an entry for column A is "A". Then there are two entries for the max value of column C. The selected value for it from column B is more or less random.

Count distinct by link on sql?

I'm trying to count distinct by the link between two columns.
Here is the example.
rownum
type
id
1
A
a
2
A
b
3
B
b
4
B
c
5
C
c
6
C
d
If I count distinct by type column, it returns 3. However, what I'd like to do is to consider rownum 2 and 3, 4 and 5 are not distinctive because they got the same value on id column.
To rephrase,
type
array of id
A
a, b
B
b, c
C
c, d
Since A and B got same b, and B and C got same c on their arrays, it would return 1 as a result.
I have no idea where to start. Would appreciate if I can get any hint or something.
Consider below:
you might use STRING_AGG
WITH TMP_TBL AS
(
SELECT 1 AS ROWNUM, 'A' AS TYPE, 'a' AS ID UNION ALL
SELECT 2,'A','b' UNION ALL
SELECT 3,'B','b' UNION ALL
SELECT 4,'B','b' UNION ALL
SELECT 5,'C','c' UNION ALL
SELECT 6,'C','d'
);
SELECT DISTINCT TYPE,N_ID
FROM
(
SELECT TYPE,STRING_AGG(ID)OVER(PARTITION BY TYPE) AS N_ID FROM TMP_TBL
)

Oracle: Analytical functions Sub totals after each change in value

I have the following data (order of records as in the example):
A B
1 10
1 20
1 30
1 40
2 50
2 65
2 75
1 89
1 100
from SQL:
with x as (
select A, B
from (
select 1 as A, 10 as B from dual
union all
select 1 as A, 20 as B from dual
union all
select 1 as A, 30 as B from dual
union all
select 1 as A, 40 as B from dual
union all
select 2 as A, 50 as B from dual
union all
select 2 as A, 65 as B from dual
union all
select 2 as A, 75 as B from dual
union all
select 1 as A, 89 as B from dual
union all
select 1 as A, 100 as B from dual
)
)
select A, B
from X
I want to group the data for each change of value in column A,
I want to get the following result:
A MIN(B) MAX(B)
1 10 40
2 50 75
1 89 100
How to get such a result in the ORACLE 11. I would expect a simple implementation...
This is a gaps and islands problem, solved using row_number analytic function
SELECT a,
MIN(b),
MAX(b)
FROM (
SELECT x.*,
ROW_NUMBER() OVER(
ORDER BY b
) - ROW_NUMBER() OVER(
PARTITION BY a
ORDER BY b
) AS seq
FROM x
)
GROUP BY a,
seq;
Demo

Select a single maximum or minimum value in entire table of oracle

select maximum value from different columns of the table
For example, Table
A B C
-------
1 2 3
4 5 6
7 8 9
Result would be like
Max
9
Assuming the values are never NULL, I would simply do:
select max(greatest(a, b, c))
from t;
You could also phrase this as:
select greatest(max(a), max(b), max(c))
from t;
This version is more resilient to NULL values. It will work with NULLs unless all values for a column are NULL.
Here's one option, which uses GREATEST and LEAST functions, enclosed into MAX and MIN aggregates:
SQL> with test (a, b, c) as
2 (select 1, 2, 3 from dual union all
3 select 4, 5, 6 from dual union all
4 select 7, 8, 9 from dual
5 )
6 select max(greatest(a, b, c)) max_result,
7 min(least(a, b, c)) min_result
8 from test;
MAX_RESULT MIN_RESULT
---------- ----------
9 1
SQL>
What about:
select greatest(max(a), max(b), max(c))
from your_table;
Or:
select max(x)
from (select max(a) as x from your_table union all
select max(b) from your_table union all
select max(c) from your_table union all
)
You can try this
select max(value) as Max from (
select max(A) as value from example
union
select max(B) as value from example
union
select max(C) as value from example ) as tab;
It will also handle the NULL values present in the column.
WITH tempData (a, b, c) AS (SELECT NULL, 2, 3 FROM DUAL UNION ALL SELECT 4, 5, 6 FROM DUAL
UNION ALL SELECT 7, 8, NULL FROM DUAL)
SELECT GREATEST(MAX(a), MAX(b), MAX(c)) AS maxval, LEAST(MIN(a), MIN(b), MIN(c)) AS minval FROM tempData;
How about?
select greatest(NVL(c1, 0),NVL(c2, 0),NVL(c3, 0), NVL(c4, 0)) from T

Running count but reset on some column value in select query

I want to achieve a running value, but condition is reset on some specific column value.
Here is my select statement:
with tbl(emp,salary,ord) as
(
select 'A',1000,1 from dual union all
select 'B',1000,2 from dual union all
select 'K',1000,3 from dual union all
select 'A',1000,4 from dual union all
select 'B',1000,5 from dual union all
select 'D',1000,6 from dual union all
select 'B',1000,7 from dual
)
select * from tbl
I want to reset count on emp B if the column value is B, then count is reset to 0 and started again increment by 1:
emp salary ord running_count
A 1000 1 0
B 1000 2 1
K 1000 3 0
A 1000 4 1
B 1000 5 2
D 1000 6 0
B 1000 7 1
Here order column is ord.
I want to achieve the whole thing by select statement, not using the cursor.
You want to define groups were the counting takes place. Within a group, the solution is row_number().
You can define the group by doing a cumulative sum of B values. Because B ends the group, you want to count the number of B after each record.
This results in:
select t.*,
row_number() over (partition by grp order by ord) - 1 as running_count
from (select t.*,
sum(case when emp = 'B' then 1 else 0 end) over (order by ord desc) as grp
from tbl t
) t;