表結構:`id` (PK)、`phone`、`create_time`。需按 `phone` 去重,**保留每組 `create_time` 最早的一條完整記錄**(含 id、phone、create_time)。
SELECT id, phone, create_time
FROM (
SELECT
id,
phone,
create_time,
ROW_NUMBER() OVER (PARTITION BY phone ORDER BY create_time ASC) AS rn
FROM your_table
) t
WHERE rn = 1;
| 方案 | 語法 | 性能 | 適用版本 | 備註 |
|---|---|---|---|---|
| ROW_NUMBER (推薦) | 標準 SQL:2003 | 優,單掃描 | Oracle 10g+ | 最通用、可移植 |
| KEEP (DENSE_RANK FIRST) | Oracle 專有 | 優 | Oracle 9i+ | 只能取聚合值,難取完整行 |
| 子查詢 + MIN(create_time) | 傳統 SQL | 差,多次掃描/連接 | 所有版本 | 需再 JOIN 回表取 id |
| RANK / DENSE_RANK | 標準 SQL | 同 ROW_NUMBER | Oracle 10g+ | 若時間相同會產生多行 rn=1 |
ROW_NUMBER() OVER (PARTITION BY phone ORDER BY create_time DESC) -- 降序
原最佳回答給出 `ROW_NUMBER()` 核心代碼並附參考鏈接,上文補充完整語法解析、替代方案對比表、索引優化建議、最晚記錄寫法,更適合直接落地。