Rank function gives incorrect Ranking - sql

select distinct a.pattern ,convert(numeric(18,0) ,isnull(b.[DCount]as [DCount]
,DENSE_RANK () OVER ( Partition by a.pattern order by b.[DCount]desc ) as [Rank]
from a, b
Gives output as
Pattern Dcount Rank
A 0 1
A 0 1
A 0 2
A 0 2
B 0 2
B 0 2
B 0 2
B 0 2
C 0 2
C 0 2
C 0 2
Whereas required output is
Pattern Dcount Rank
A 0 1
A 0 1
A 0 1
A 0 1
B 0 1
B 0 1
B 0 1
B 0 1
C 0 1
C 0 1
C 0 1

Perhaps you just want the ranking by dcount. If so:
select distinct a.pattern, convert(numeric(18,0),
coalesce(b.DCount, 0) as DCount,
dense_rank() over (order by b.[DCount] desc) as [Rank]
from a cross join b;

use DENSE_RANK below way
select * ,DENSE_RANK () OVER ( order by Pattern, Dcount) as rn from t

Try this: you need to partition by Pattern,dcount and order by only pattern
demo
select *,dense_Rank() over(partition by Pattern,dcount order by Pattern) from tablename

Related

Select table adding columns with data depending on duplicates in other column

Imagine this data.
Id
Type
1
A
1
B
1
B
2
A
3
B
I want to select table and ad two columns turning it to this. How can i do it? (In teradata)
Id
Type
Id with both A+B
Id with only A
1
A
1
0
1
B
1
0
1
B
1
0
2
A
0
1
3
B
0
0
I'm not familiar with teradata but in standard SQL next query should be working:
SELECT
T.*,
CASE WHEN Cnt = 2 THEN 1 ELSE 0 END AS BOTH_TYPES_PRESENT,
CASE WHEN Cnt = 1 AND Type = 'A' THEN 1 ELSE 0 END AS ONLY_A_PRESENT
FROM T
LEFT JOIN (
SELECT Id, COUNT(DISTINCT Type) Cnt FROM T WHERE Type IN ('A', 'B') GROUP BY Id
) CNT ON T.Id = CNT.Id;
SQL online editor

How can I create a new table by deleted duplicated rows in SQL?

I have a table which looks like this
ID A B C
1 1 0 0
1 1 0 0
2 1 1 0
2 1 1 0
How can I remove the duplicated rows in SQL so that I am left with a table that looks like this:
ID A B C
1 1 0 0
2 1 1 0
use row_number()
with cte as
(
select *, row_number() over(partition by id order by id) as rn
from tablename
)
delete from cte where rn<>1
select distinct * from <table_name>
This is the simplest way.

MS Sql Server, same column with a different row neighbors

I need a little help on a SQL query. I could not get the result that I wanted.
ID I10 H 10NS HNS CC NSCC
0 1 1 1 1 14 14
1 0 1 0 1 6 2
1 0 2 0 2 12 2
1 0 3 0 3 17 4
1 0 3 0 3 18 4
1 0 3 0 3 19 4
1 0 3 0 3 20 4
What I want to have is one from each ID with highest CC
For example,
ID I10 H 10NS HNS CC NSCC
0 1 1 1 1 14 14
1 0 3 0 3 20 4
I tried with this code:
SELECT a.ID, b.name, a.i10 as[i-10-index], a.h as[h-index], 10ns as[i-10-index based on non-self-citation], a.hns as [h-index based on non-self-citation],
max(a.[Citation Count]), (a.[Non-Self-Citation Count])
FROM tbl_lpNumerical as a
join tbl_lpAcademician as b
on a.ID= (b.ID-1)
GROUP BY a.ID, b.name, a.i10, a.h, a.10ns, a.hns,
a.[Non-Self-Citation Count]
order by a.ID desc
However, I could not get the desired results.
Thank you for your time.
You can simply get all the row where not exist another row with an higher CC
SELECT n.*
FROM tbl_lpNumerical n
WHERE NOT EXISTS ( SELECT 'b'
FROM tbl_lpNumerical n2
WHERE n2.ID = n.ID
AND n2.CC > n.CC
)
In SQL Server, you can use row_number() for this. Based on your sample data`, something like:
select sd.*
from (select sd.*, row_number() over (partition by id order by cc desc) as seqnum
from sampledata sd
) sd
where seqnum = 1;
I have no idea what your query has to do with the sample data. If it generates the data, then you can use a CTE:
with sampledata as (
<some query here>
)
select sd.*
from (select sd.*, row_number() over (partition by id order by cc desc) as seqnum
from sampledata sd
) sd
where seqnum = 1;
The following query will select a single row from each ID partition: the one with the highest CC value:
SELECT *
FROM (SELECT *,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY CC DESC) AS rn
FROM mytable) t
WHERE t.rn = 1
If there can be multiple rows having the same CC max value and you want all of them selected, then you can replace ROW_NUMBER() with RANK().

Clause ORDER BY

I have a problem with a select in sql server, i have this table with 2 columns:
a 2
b 1
c 100
d 1
a 100
b 1
c 2
d 1
I want ordered it based on the first column,in this way:
a 2
a 100
b 1
b 1
c 2
c 100
d 1
d 1
But then j want the rows with secondcolumn=100 be moved at the bottom,so:
a 2
b 1
b 1
c 2
d 1
d 1
a 100
c 100
I have tried with clause ORDER BY column1 ASC, (column2=100) ASC,but it didnt work!
Thankyou and greetings.
Actually, you want the rows with 100 in the second column moved to the bottom first, and then ordered by the first column:
order by (case when col2 = 100 then 1 else 0 end),
col1
Use the CASE expression as below
SELECT *
FROM tab
ORDER BY CASE
WHEN column2 = 100 THEN 1
ELSE 0
END ASC,
column1 asc
SELECT *
FROM table1
ORDER BY
CASE
WHEN col2>=100 THEN 1
ELSE 0
END,
col1,
col2
SQLFiddle Example

SQL selecting from a particular duplicate row

Hi all I have a sql query
SELECT FKid1, FKID2, a, b, c
from [source]
where FKID1 = 3
which returns the following data set so
(hope formatting holds)
FKID1 FKID2 A B C
3 40297 0 0 2
3 40297 0 100 1
3 40325 0 0 2
3 40325 0 0 3
3 40325 0 10 -1
3 40348 0 10 3
3 40391 0 10 -1
3 40392 0 10 -1
3 40501 0 10 -1
3 40501 0 0 2
I'm trying to improve this query so that if there are 2 rows with duplicate FKID1 and FKID2 values, it will pick the column B value from a particular row as follows...
if there is a row with C = -1 use the B value in this row and ignore others.
if there are 2 rows with C <> -1 then pick the MAX(B) value.
For rows that are not duplicated, return as normal.
IE the results should look as follows...
FKID1 FKID2 A B C
3 40297 0 100 1
3 40325 0 10 -1
3 40348 0 10 3
3 40391 0 10 -1
3 40392 0 10 -1
3 40501 0 10 -1
the correct values selected for the B column and no dupes.
We have a solution at the moment, but I think it's overcomplicated and wondered if anyone had any ideas?
Thanks.
One way
;WITH cte As
(
SELECT FKid1, FKID2, a, b, c,
ROW_NUMBER() OVER (PARTITION BY FKID1, FKID2
ORDER BY CASE WHEN C = -1 THEN 0 ELSE 1 END ASC, B DESC) AS RN
from [source]
where FKID1 = 3
)
SELECT FKid1, FKID2, a, b, c
FROM cte
WHERE RN=1
Select T1.FKID1, T1.FKID2
, Min(A) As A
, Case
When Count(*) = 2 And NegCB.B Is Not Null Then Max(NegCB.B)
Else Max(B)
End As B
, Min(C) As C
From Source As T1
Outer Apply (
Select T3.B
From Source As T3
Where T2.FKID1 = T1.FKID1
And T2.FKID2 = T1.FKID2
And T2.C = -1
) As NegCB
Where FKID1= 3
Group By T1.FKID1, T1.FKID2