如何使用 group by 检索不同的数据
How can I retrieve distinct data by using group by
我有以下 table 及其示例数据,
+------------------+-------+--------+---------------------+-------+
| 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 |
+------------------+-------+--------+---------------------+-------+
我需要将 PhoneCode
与最新的 SeqID
区分开来。所以我尝试了以下查询。
SELECT UD.PHONECODE, UD.SeqID, UD.ACTIVE, UD.Token
FROM DEVICE UD
WHERE UD.CUSID = '50002' AND UD.ACTIVE = 'I'
GROUP BY PHONECODE
但是它出错了。如何检索以下输出?
+------------------+-------+--------+---------------------+-------+
| PhoneCode | SeqID | Active | Token | CUSID |
+------------------+-------+--------+---------------------+-------+
| e29a5e1c695352b8 | 3900 | I | JYN8CYRVzaKWL-l_K | 50002 |
+------------------+-------+--------+---------------------+-------+
| 741fb28bc72183e3 | 3899 | I | RU3ReKEw0yin9LxZWCO | 50002 |
+------------------+-------+--------+---------------------+-------+
您可以使用 MAX()
和一个连接:
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
没有 GROUP BY
和 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;
或者,如果你想使用 GROUP BY
那么你也可以使用 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;
其中,对于示例数据:
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;
双输出:
PHONECODE
SEQID
ACTIVE
TOKEN
741fb28bc72183e3
3899
I
RU3ReKEw0yin9LxZWCO
e29a5e1c695352b8
3900
I
JYN8CYRVzaKWL-l_K
db<>fiddle here
简单的子查询怎么样
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
)
以下查询将起作用:
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
如果您的数据库版本是 12c+
并且显示 ROW_NUMBER()
函数的返回值无关紧要,那么没有子查询的作为选项的查询将是
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
其中 rn
的所有关系(相等值)都包含在结果集中。
我有以下 table 及其示例数据,
+------------------+-------+--------+---------------------+-------+
| 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 |
+------------------+-------+--------+---------------------+-------+
我需要将 PhoneCode
与最新的 SeqID
区分开来。所以我尝试了以下查询。
SELECT UD.PHONECODE, UD.SeqID, UD.ACTIVE, UD.Token
FROM DEVICE UD
WHERE UD.CUSID = '50002' AND UD.ACTIVE = 'I'
GROUP BY PHONECODE
但是它出错了。如何检索以下输出?
+------------------+-------+--------+---------------------+-------+
| PhoneCode | SeqID | Active | Token | CUSID |
+------------------+-------+--------+---------------------+-------+
| e29a5e1c695352b8 | 3900 | I | JYN8CYRVzaKWL-l_K | 50002 |
+------------------+-------+--------+---------------------+-------+
| 741fb28bc72183e3 | 3899 | I | RU3ReKEw0yin9LxZWCO | 50002 |
+------------------+-------+--------+---------------------+-------+
您可以使用 MAX()
和一个连接:
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
没有 GROUP BY
和 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;
或者,如果你想使用 GROUP BY
那么你也可以使用 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;
其中,对于示例数据:
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;
双输出:
PHONECODE SEQID ACTIVE TOKEN 741fb28bc72183e3 3899 I RU3ReKEw0yin9LxZWCO e29a5e1c695352b8 3900 I JYN8CYRVzaKWL-l_K
db<>fiddle here
简单的子查询怎么样
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
)
以下查询将起作用:
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
如果您的数据库版本是 12c+
并且显示 ROW_NUMBER()
函数的返回值无关紧要,那么没有子查询的作为选项的查询将是
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
其中 rn
的所有关系(相等值)都包含在结果集中。