You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改SQL查询仅获取唯一ID?求Distinct实现方案

问题:使用DISTINCT消除查询结果中的重复ID

现有数据集

Order_Table

SELECT *
INTO Order_Table
FROM (VALUES
   (1,          456,       'repair',       'House'),
   (2,          456,        'paint',       'House'),
   (3,          678,        'repair',      'Fence'),
   (4,          789,        'repair',      'House'),
   (5,          789,        'paint',       'House'),
   (6,          789,        'repair',      'Fence'),
   (7,          789,        'paint',       'Fence')
   )
v (OrderNum,    CustomerNum, OrderDesc,   Structure)

Veg_Table

SELECT *
INTO Veg_Table
FROM (VALUES
   (1,       '12/01/2020'),
   (2,       '12/02/2020'),
   (3,       '12/03/2020'),
   (4,       '12/04/2020'),
   (5,       '12/05/2020'),
   (6,       '12/06/2020'),
   (7,       '12/07/2020'),
   (1,       '12/10/2020'),
   (2,       '12/11/2020'),
   (3,       '12/12/2020')
   )
v (ID,   MyDate)

原查询语句

Select Distinct CTE.ID, *
From (
Select *
From Order_Table as Hist
Inner Join Veg_Table As Veg
On Hist.OrderNum = Veg.ID) as CTE

问题说明

上述查询返回重复的ID,尝试过Where In (Select Distinct ID From Event_View)也无效。期望得到每个ID唯一的结果集,如下:

OrderNum    CustomerNum    OrderDesc    Structure   ID    MyDate
1           456            repair       House       1     12/1/2020
2           456            paint        House       2     12/2/2020
3           678            repair       Fence       3     12/3/2020
4           789            repair       House       4     12/4/2020
5           789            paint        House       5     12/5/2020
6           789            repair       Fence       6     12/6/2020
7           789            paint        Fence       7     12/7/2020

已知可以用Row_Number() Over (Partition By ID)实现,但希望用更简单的DISTINCT方案解决,请问该如何修改查询?


解决方案

问题出在SELECT DISTINCT CTE.ID, *的写法上:*会包含所有字段,包括重复的MyDate值,而DISTINCT是对整行所有字段去重,不是只针对ID。因为同一个ID对应不同的MyDate,所以整行是不同的,DISTINCT无法消除这些重复ID的行。

要实现需求,你需要先对Veg_Table按ID去重(只保留每个ID对应的一条MyDate,比如最早的),再和Order_Table关联,具体方案如下:

方案1:PostgreSQL适用(用DISTINCT ON去重)

SELECT Hist.*, Veg.ID, Veg.MyDate
FROM Order_Table AS Hist
INNER JOIN (
    SELECT DISTINCT ON (ID) ID, MyDate
    FROM Veg_Table
    ORDER BY ID, MyDate -- 保留最早的日期,可根据需求调整排序规则
) AS Veg ON Hist.OrderNum = Veg.ID

方案2:通用SQL(用GROUP BY去重)

如果是SQL Server等不支持DISTINCT ON的数据库,改用GROUP BY聚合取每个ID的目标日期:

SELECT Hist.*, Veg.ID, Veg.MyDate
FROM Order_Table AS Hist
INNER JOIN (
    SELECT ID, MIN(MyDate) AS MyDate -- 取最早日期,也可换MAX取最晚
    FROM Veg_Table
    GROUP BY ID
) AS Veg ON Hist.OrderNum = Veg.ID

方案3:直接关联后用GROUP BY替代DISTINCT

也可以直接在关联后通过分组聚合实现唯一ID的结果:

SELECT 
    Hist.OrderNum, 
    Hist.CustomerNum, 
    Hist.OrderDesc, 
    Hist.Structure, 
    Veg.ID, 
    MIN(Veg.MyDate) AS MyDate
FROM Order_Table AS Hist
INNER JOIN Veg_Table AS Veg ON Hist.OrderNum = Veg.ID
GROUP BY Hist.OrderNum, Hist.CustomerNum, Hist.OrderDesc, Hist.Structure, Veg.ID

核心逻辑是:必须先消除Veg_Table中同一个ID的多条记录,或者通过聚合函数将同一个ID的多条记录合并为一条,这样关联后才不会出现重复ID的行,最终得到符合预期的唯一ID结果集。


内容的提问来源于stack exchange,提问作者ASH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 21:05:10