SQL: create a query with a column identifying each tuple of values - sql

I've been trying to find a solution for this SQL query:
|A| |B| |Output|
===========================
1 A 1
1 A 1
1 B 2
1 C 3
2 C 1
2 D 2
2 F 3
2 H 4
3 D 1
3 D 1
3 I 2
As you can see, I want to create a column (output) that identifies, not counts or sums, the occurrence of each (A,B) tuple, without removing repeated occurences.
How would you do that?
Thanks in advance

Look up SQL Server Built-in DENSE_RANK() function.
SELECT *
,DENSE_RANK() OVER (PARTITION BY [A] ORDER BY [B] ASC) AS [OutPut]
FROM TableName

I think you want dense_rank():
select t.*,
dense_rank() over (partition by a order by b)
from table t;

Related

SQL: How to assign the same line number to lines with the same value?

I have a table like below in SQL Server. I reach the row number values with using ROW_NUMBER partition function. But this was not the result I wanted to achieve.
RowNumber
Value
1
A
2
A
3
A
1
B
2
B
1
C
1
D
I want to get this table
RowNumber
Value
1
A
1
A
1
A
2
B
2
B
3
C
4
D
How can I do it, do you have a function suggestion?
Use DENSE_RANK instead of ROW_NUMBER
SELECT DENSE_RANK() OVER (ORDER BY VALUE), VALUE
FROM TABLE
Use DENSE_RANK:
SELECT DENSE_RANK() OVER (ORDER BY Value) RowNumber, Value
FROM yourTable
ORDER BY Value;

How to select the last value which is not null?

I have the following table:
id a b
1 1 kate
1 4 null
1 3 paul
1 3 paul
1 2 lola
2 1 kim
2 9 null
2 2 null
In result it should be this:
1 3 paul
2 1 kim
I want to get the last a where b is not null. Something like:
select b
from (select,b
row_num() over (partition by id order by a desc) as num) as f
where num = 1
But this way I get a null value, because to the last a = 4 corresponds to b IS NULL. Maybe there is a way to rewrite ffill method from pandas?
Assuming:
a is defined NOT NULL.
You want the row with the greatest a where b IS NOT NULL - per id.
SELECT DISTINCT ON (id) *
FROM tbl
WHERE b IS NOT NULL
ORDER BY id, a DESC;
db<>fiddle here
Detailed explanation:
Select first row in each GROUP BY group?
Try:
select id, a, b
from (select id, a, b,
row_num() over (partition by id order by a desc nulls last) as num
from unnamedTable) t
where num = 1
Or, if that isn't right, try it with nulls first. I can never remember which way it works with desc.
If you aren't guaranteed to have at least one non-null per id then you'll want to move nulls to the bottom of the list rather than filtering those rows out entirely.
select id, a, b
from (
select id, a, b,
row_number() over (
partition by id
order by case when b is not null then 0 else 1 end, a desc
) as num
) as f
where num = 1
You can wrap this around a cte and join it back to the main table if you wish to keep the original columns as is, but looking at your expected output and logic, this should do it. Having said that, row_number() based approach might be a tad faster.
select distinct
id,
max(a) over (partition by id) as a,
first_value(b) over (partition by id order by a desc) as b
from tbl
where b is not null;

SQL query to find the entries corresponding to the maximum count of each type

I have a table X in Postgres with the following entries
A B C
2 3 1
3 3 1
0 4 1
1 4 1
2 4 1
3 4 1
0 5 1
1 5 1
2 5 1
3 5 1
0 2 2
1 2 3
I would like to find out the entries having maximum of Column C for every kind of A and B i.e (group by B) with the most efficient query possible and return corresponding A and B.
Expected Output:
A B C
1 2 3
2 3 1
0 4 1
0 5 1
Please help me with this problem . Thank you
demo: db<>fiddle
Using DISTINCT ON:
SELECT DISTINCT ON (B)
A, B, C
FROM
my_table
ORDER BY B, C DESC, A
DISTINCT ON gives you exactly the first row for an ordered group. In this case B is grouped.
After ordering B (which is necessary): We first order the maximum C (with DESC) to the top of each group. Then (if there are tied MAX(C) values) we order the A to get the minimum A to the top.
Seems like it is a greatest n per group problem:
WITH cte AS (
SELECT *, RANK() OVER (PARTITION BY B ORDER BY C DESC, A ASC) AS rnk
FROM t
)
SELECT *
FROM cte
WHERE rnk = 1
You're not clear which A needs to be considered, the above returns the row with smallest A.
itseems to me you need max()
select A,B, max(c) from table_name
group by A,B
this will work:
select * from (SELECT t.*,
rank() OVER (PARTITION BY A,B order by C) rank
FROM tablename t)
where rank=1 ;

Assigning row number according to the Column value SQL Server?

I have a table like this in SQL server 2014:
name
a
a
b
b
b
c
d
d
d
I want to create another column that is S.No. , but serial number value will be assigned according to name column. If name occurs 2 times the value of s.no. will be 1 and 2.If d is 3 times than value for d will be 1,2 and 3 and than again counter will start with 1 for e. so the table will be like:
name S.no.
a 1
a 2
b 1
b 2
b 3
c 1
d 1
d 2
d 3
Any solution? thanks for the help.
Use ROW_NUMBER():
SELECT name, ROW_NUMBER() OVER (PARTITION BY name ORDER BY (SELECT 1)) [S.no.]
FROM T
Just in another way by using Count()
select
Name,
Count(1) over (partition by Name ORDER BY Name ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as Slno
from MyTable

Increment Row Number on Group

I am working on a query for SQL Server 2005 that needs to return data with two 'index' fields. The first index 't_index' should increment every time the 'shade' column changes, whilst the second index increments within the partition of the values in the 'shade' column:
t_index s_index shade
1 1 A
1 2 A
1 3 A
1 4 A
1 5 A
2 1 B
2 2 B
2 3 B
2 4 B
2 5 B
To get the s_index column I am using the following:
Select ROW_NUMBER() OVER(PARTITION BY [shade] ORDER BY [shade]) as s_index
My question is how to get the first index to only increment when the value in the 'shade' column changes?
That can be accomplished with the DENSE_RANK() function:
DENSE_RANK() OVER(Order By [shade]) as t_index
You can try to use DENSE_RANK() for that:
SELECT
shade,
s_index = ROW_NUMBER() OVER(PARTITION BY [shade] ORDER BY [shade]),
t_index = DENSE_RANK() OVER (ORDER BY [shade])
FROM dbo.YourTableNameHEre
Gives output:
shade s_index t_index
A 1 1
A 2 1
A 3 1
A 4 1
A 5 1
B 1 2
B 2 2
B 3 2
B 4 2
B 5 2