如何使用Distinct从表中仅选择一个唯一记录

Nub*_*iya 7 oracle distinct greatest-n-per-group

我的表有几条具有相同MemberID的记录.我想只得到一条记录.

select DISTINCT(MemberID)  from AnnualFees;
Run Code Online (Sandbox Code Playgroud)

然后结果会来.但我想显示其他列数据,但当我这样做

select DISTINCT(MemberID),StartingDate,ExpiryDate,Amount  from AnnualFees;
Run Code Online (Sandbox Code Playgroud)

所有细节,包括相同的MemberID数据也显示.

有人能帮我吗.

Ton*_*ews 20

假设你只想为每个memberid随机选择任何行,你可以这样做:

select memberid, this, that, theother
from
(
select memberid, this, that, theother,
       row_number() over (partition by memberid order by this) rn
from   annualfees
)
where rn = 1;
Run Code Online (Sandbox Code Playgroud)

如果你想要每个memberid一个特定的行,例如具有最新StartDate的行,那么你可以将其修改为:

select memberid, this, that, theother
from
(
select memberid, this, that, theother,
       row_number() over (partition by memberid order by StartDate desc) rn
from   annualfees
)
where rn = 1;
Run Code Online (Sandbox Code Playgroud)

  • @Martin:您的解决方案的一个优点是Oracle在返回行之前不必读取所有`annualfees`行:它可以返回行,因为它找到满足where子句的行,而分析解决方案必须读取**返回第一批之前的所有**行.如果您只对前几行感兴趣(如果表格非常大),您会发现查询返回的速度更快.*(一如既往权衡)* (2认同)

Mar*_*ark 6

不知道这是否是您需要的,但您可能需要查看GROUP BY而不是DISTINCT ......

如果你有几个具有相同成员ID的记录,你可能需要指定exaclty如何从其他人识别你想要的那个

例如,获取每个成员的最后开始日期:

SELECT memberid, max(startingdate)
FROM annualfees
GROUP BY memberid
Run Code Online (Sandbox Code Playgroud)

但是如果你需要以这种方式识别一条记录而且还要显示其他列,我想你可能需要像这样做一些诡计 ......

例如,使用连接子查询上面的SELECT以连接您想要的其他列:

SELECT subq.memid, subq.startdate, a.expirydate, a.amount
FROM (
  SELECT memberid AS memid, max(startingdate) AS startdate
  FROM annualfees
  GROUP BY memberid ) subq
INNER JOIN annualfees a ON a.memberid = subq.memid 
               AND a.startingdate = subq.startdate
Run Code Online (Sandbox Code Playgroud)

从头到尾,还显示数据表(使用"SET VERIFY ON"跟踪/抓取o/p)...

-- show all rows
select *
from annualfees
order by memberid, startingdate
MEMBERID               STARTINGDATE              EXPIRYDATE           AMOUNT               
---------------------- ------------------------- -------------------- -------------------- 
1                      02-DEC-09                 05-FEB-10            111                  
1                      25-JUN-10                 25-JUN-11            222                  
2                      25-APR-10                 25-JUN-13            333                  

3 rows selected

/
-- show one member`s data using max(startingdate) as selector.
SELECT memberid, max(startingdate)
    FROM annualfees
    GROUP BY memberid
MEMBERID               MAX(STARTINGDATE)         
---------------------- ------------------------- 
1                      25-JUN-10                 
2                      25-APR-10                 

2 rows selected

/ 
-- show above data joined with the other columns.
SELECT subq.memid, subq.startdate, a.expirydate, a.amount
    FROM (
      SELECT memberid AS memid, max(startingdate) AS startdate
      FROM annualfees
      GROUP BY memberid ) subq
    INNER JOIN annualfees a ON a.memberid = subq.memid AND a.startingdate = subq.startdate
MEMID                  STARTDATE                 EXPIRYDATE           AMOUNT               
---------------------- ------------------------- -------------------- -------------------- 
1                      25-JUN-10                 25-JUN-11            222                  
2                      25-APR-10                 25-JUN-13            333                  

2 rows selected

/
Run Code Online (Sandbox Code Playgroud)