'How can I retrieve distinct data by using group by
I have following table and its sample data as follows,
+------------------+-------+--------+---------------------+-------+
| PhoneCode | SeqID | Active | Token | CUSID |
+------------------+-------+--------+---------------------+-------+
| e29a5e1c695352b8 | 3898 | I | JYN8CYRVzaKWL-l_K | 50002 |
+------------------+-------+--------+---------------------+-------+
| e29a5e1c695352b8 | 3900 | I | JYN8CYRVzaKWL-l_K | 50002 |
+------------------+-------+--------+---------------------+-------+
| 741fb28bc72183e3 | 3899 | I | RU3ReKEw0yin9LxZWCO | 50002 |
+------------------+-------+--------+---------------------+-------+
| 741fb28bc72183e4 | 3901 | A | RU3ReKEw0yin9LxZWCO | 50002 |
+------------------+-------+--------+---------------------+-------+
I need to take distinct PhoneCode with latest SeqID. So I tried following query.
SELECT UD.PHONECODE, UD.SeqID, UD.ACTIVE, UD.Token
FROM DEVICE UD
WHERE UD.CUSID = '50002' AND UD.ACTIVE = 'I'
GROUP BY PHONECODE
But its makes error. How can I retrieve following output?
+------------------+-------+--------+---------------------+-------+
| PhoneCode | SeqID | Active | Token | CUSID |
+------------------+-------+--------+---------------------+-------+
| e29a5e1c695352b8 | 3900 | I | JYN8CYRVzaKWL-l_K | 50002 |
+------------------+-------+--------+---------------------+-------+
| 741fb28bc72183e3 | 3899 | I | RU3ReKEw0yin9LxZWCO | 50002 |
+------------------+-------+--------+---------------------+-------+
Solution 1:[1]
You can do it without GROUP BY and without self-joins:
SELECT PHONECODE,
SeqID,
ACTIVE,
Token
FROM (
SELECT d.*,
ROW_NUMBER() OVER (PARTITION BY phonecode ORDER BY seqid DESC) AS rn
FROM device d
WHERE cusid = 50002
AND active = 'I'
)
WHERE rn = 1;
Or, if you want to use GROUP BY then you can also use KEEP:
SELECT PHONECODE,
MAX(SeqID) AS seqid,
MAX(ACTIVE) KEEP (DENSE_RANK LAST ORDER BY SeqID) AS active,
MAX(Token) KEEP (DENSE_RANK LAST ORDER BY SeqID) AS token
FROM device
WHERE cusid = 50002
AND active = 'I'
GROUP BY phonecode;
Which, for the sample data:
CREATE TABLE device (PhoneCode, SeqID, Active, Token, CUSID ) AS
SELECT 'e29a5e1c695352b8', 3898, 'I', 'JYN8CYRVzaKWL-l_K', 50002 FROM DUAL UNION ALL
SELECT 'e29a5e1c695352b8', 3900, 'I', 'JYN8CYRVzaKWL-l_K', 50002 FROM DUAL UNION ALL
SELECT '741fb28bc72183e3', 3899, 'I', 'RU3ReKEw0yin9LxZWCO', 50002 FROM DUAL UNION ALL
SELECT '741fb28bc72183e4', 3901, 'A', 'RU3ReKEw0yin9LxZWCO', 50002 FROM DUAL;
Both output:
PHONECODE SEQID ACTIVE TOKEN 741fb28bc72183e3 3899 I RU3ReKEw0yin9LxZWCO e29a5e1c695352b8 3900 I JYN8CYRVzaKWL-l_K
db<>fiddle here
Solution 2:[2]
What about a simple sub query
SELECT UD.PHONECODE, UD.SeqID, UD.ACTIVE, UD.Token
FROM device ud
WHERE (UD.PHONECODE, UD.SeqID) IN (
SELECT PHONECODE, MAX(SeqID)
FROM device
WHERE CUSID = '50002' AND ACTIVE = 'I'
GROUP BY PHONECODE
)
Solution 3:[3]
You can use MAX() and a join:
SELECT UD.PHONECODE, UD.ACTIVE, UD.Token, UD.SeqID
FROM DEVICE UD
INNER JOIN (
SELECT PHONECODE, MAX(SeqID) as SEQID
FROM DEVICE
WHERE CUSID = '50002' AND ACTIVE = 'I'
GROUP BY PHONECODE
) T2 ON UD.PHONECODE = T2.PHONECODE AND UD.SEQID = T2.SEQID
Solution 4:[4]
The following query will work :
select phonecode,seqid,active,token,cusid
from
(
select * , row_number() over(partition by phonecode order by seqid desc) as rownum
from device
where cusid = 50002 and active = 'I'
) as t1
where rownum = 1
Solution 5:[5]
If your database version is 12c+ and displaying the returning value of ROW_NUMBER() function doesn't matter, then such a query as an option without a subquery would be
SELECT d.*,
ROW_NUMBER() OVER (PARTITION BY PhoneCode ORDER BY SeqID DESC) AS rn
FROM device d
WHERE cusid = 50002
AND active = 'I'
ORDER BY rn
FETCH FIRST 1 ROWS WITH TIES
where all ties(equal values) of rn are included in the result set.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | MT0 |
| Solution 3 | MT0 |
| Solution 4 | debaNik Joardar |
| Solution 5 | Barbaros Özhan |
