From the table data I should derive the Rank column.
Aim is to select Unique Duns based on below conditions:
Max(ConfidenceCode)
If Confindencde is same, If DeliveryAddressSeq=0 has just one row select that
If Confindencde is same, If DeliveryAddressSeq=0 has many rows then select min of CustomerCode
So, finally I require Rank=1 data as desired output
The rank window function should do the trick:
SELECT Duns, ConfidenceCode, DeliveryAddressSeq, CustomerCode
FROM (SELECT Duns, ConfidenceCode, DeliveryAddressSeq, CustomerCode,
RANK() OVER (PARTITION BY duns
ORDER BY ConfidenceCode ASC,
CASE DeliveryAddressSeq WHEN 0 THEN 0
ELSE 1
END ASC,
CustomerCode DESC) AS rk
FROM mytable)
WHERE rk = 1
Since you wanted to have the rank 1 only, you were looking for customercode 501, 504, 507
SELECT duns,
confidencecode,
deliveryaddressseq,
customercode,
[rank]
FROM (SELECT *,
RANK() OVER (PARTITION BY duns
ORDER BY confidencecode DESC,
deliveryaddressseq,
customercode) AS [rank]
FROM t_duns) tt
WHERE [rank] = 1
Result
duns confidencecode deliveryaddressseq customercode rank
1001 10 1 501 1
1002 10 0 504 1
1003 10 0 507 1
Related
Is there a way to assign a value ("IdNo") sequentially, 1 and 2, per CustNo? Below is my query (or I can put this query in a view), but not sure how to add an "IdNo" column that will just assign a "1" and "2" respectively, per unique CustNo.
with row as
(select z.*,
row_number ()
over (partition by CustNo
order by FoodDate desc) rn
from table z)
select CustNo,
Food,
FoodDate
from row
where rn <= 2
order by CustNo, FoodDate desc
Below is what I want it to look like with the IdNo added...
IdNo CustNo Food FoodDate
1 101 Red-Apple 7/5/22
2 101 Red-Apple 7/5/22
1 256 Red-Apple 7/11/22
2 256 Red-Cherry 5/20/22
1 418 Blue-Muffin 4/1/22
2 418 Blue-Berry 3/16/22
1 599 Orange-Persimmon 2/8/22
2 599 Red-Apple 1/23/22
1 654 Blue-Berry 12/4/21
2 654 Yellow-Banana 11/27/21
Just add rn on your query.
with row as
(select z.*,
row_number ()
over (partition by CustNo
order by FoodDate desc) rn
from table z)
select rn as IdNo,
CustNo,
Food,
FoodDate
from row
where rn <= 2
order by CustNo, FoodDate desc
Suppose I have a table of customer purchases ("my_table") like this:
--------------------------------------
customerid | date_of_purchase | price
-----------|------------------|-------
1 | 2019-09-20 | 20.23
2 | 2019-09-21 | 1.99
1 | 2019-09-21 | 123.34
...
I'd like to be able to find the nth highest spending customer in this table (say n = 5). So I tried this:
with cte as (
select customerid, sum(price) as total_pay,
row_number() over (partition by customerid order by total_pay desc) as rn
from my_table group by customerid order by total_pay desc)
select * from cte where rn = 5;
But this gives me nonsense results. For some reason rn doesn't seem to be unique (for example there are a bunch of customers with rn = 1). I don't understand why. Isn't rn supposed to be just a row number?
Remove the partition by in the definition of row_number():
with cte as (
select customerid, sum(price) as total_pay,
row_number() over (order by total_pay desc) as rn
from my_table
group by customerid
)
select *
from cte
where rn = 5;
You are already aggregating by customerid, so each customer has only one row. So the value of rn will always be 1.
I have a query in SQL looks like that:
select fldCustomer, fldTerminal, COUNT(fldbill)
from tblDataBills
group by fldCustomer, fldTerminal
order by fldCustomer
results looks like:
fldCustomer fldTerminal (number of bills)
0 1 19086
0 2 10
0 5 236
1 1 472
1 5 3
1 500 19
2 1 292
2 500 22
how can i get the MAX count of each customer so i get results like
0 1 19086
1 1 472
2 1 292
Thanks in advance!
Use a subquery with row_number():
select fldCustomer, fldTerminal, cnt
from (select fldCustomer, fldTerminal, COUNT(*) as cnt,
row_number() over (partition by fldCustomer order by count(*) desc) as seqnum
from tblDataBills
group by fldCustomer, fldTerminal
) db
where seqnum = 1
order by fldCustomer ;
Note that in the event of ties, this will arbitrarily return one of the rows. If you want all of them, then use rank() or dense_rank().
This might require a little trickery with the RANK() function
SELECT fldCustomer, fldTerminal, [(number of bills)]
FROM (
SELECT fldCustomer, fldTerminal, COUNT(fldbill) [(number of bills)],
RANK() OVER (PARTITION BY fldCustomer ORDER BY COUNT(fldbill) DESC) Ranking
FROM tblDataBills
GROUP BY fldCustomer, fldTerminal
) a
WHERE Ranking = 1
I want to calculate unique rankings but I get duplicate rankings
Here's my attempt:
SELECT
TG.EMPCODE,
DENSE_RANK() OVER (ORDER BY TS.COUNT_DEL DESC, TG.COUNT_TG DESC) AS YOUR_RANK
FROM
(SELECT
EmpCode,
SUM(CASE WHEN Tgenerate = 1 THEN 1 ELSE 0 END) AS COUNT_TG
FROM
TBLTGENERATE1
GROUP BY
EMPCODE) TG
INNER JOIN
(SELECT
EMP_CODE,
SUM(CASE WHEN STATUS = 'DELIVERED' THEN 1 ELSE 0 END) AS COUNT_DEL
FROM
TBLSTAT
GROUP BY
EMP_CODE) TS ON TG.EMPCODE = TS.EMP_CODE;
The output I get is like this:
EID Rank
---------
102 1
105 2
101 2
103 3
106 4
There is same rank for 105 and 101.
How do I calculate unique ranking?
Use ROW_NUMBER() instead of DENSE_RANK():
SELECT TG.EMPCODE,
ROW_NUMBER() OVER (ORDER BY TS.COUNT_DEL DESC, TG.COUNT_TG DESC) AS YOUR_RANK
Ties will then be given sequential rankings.
I have to count the unique status from multiple values. Here is my table example
Id Status OrderId
-------------------
1 1 43
2 2 43
3 1 44
Desired output
It should give the count(status) for Status '1' is 1 and Status '2' is 1. But when using count its giving 2 for status '1'.
You have to do
count(DISTINCT status)
instead of
count(status)
to get
unique status from multiple values.
EDIT:
If you want to get (not count) the Status value of the last inserted record for every OrderId, then you can do:
SELECT Status
FROM (
SELECT Id, Status, OrderId,
ROW_NUMBER() OVER (PARTITION BY OrderId
ORDER BY Id DESC) AS rn
FROM mytable ) t
WHERE t.rn = 1
If you want to get the last status for each order:
with cte as(select *, row_number()
over(partition by OrderID order by Id desc) from TableName)
select * from cte where rn = 1
Or:
select * from (select *, row_number()
over(partition by OrderID order by Id desc) from TableName) t
where rn = 1