【问题标题】:Why Duplicates in my join为什么我的加入重复
【发布时间】:2013-06-04 03:41:29
【问题描述】:

为什么我会得到重复?看起来很简单,但它并没有穿过我厚厚的头骨。

SELECT MOPACTIVITY.MOPID STRICT,
    TO_CHAR(MOPNOTES.MOPNOTEDATE, 
              'yyyy-mm-dd hh24:mi') "MOPNOTEDATE"
FROM MOPUSER.MOPACTIVITY
   INNER JOIN MOPUSER.MOPNOTES 
       ON MOPACTIVITY.MOPID=MOPNOTES.MOPID

如何仅将一条子记录提供给父级,而子记录是 MOPNOTES.MOPNOTEDATE 的最新记录?

【问题讨论】:

  • 因为MOPID 不是你桌子上的钥匙
  • 正如@Lamak 所说... MOPID 在一个或两个表中并不是唯一的。运行Select MOPID From MOPUSER.MOPACTIVITY Group By MOPID Having Count(*) > 1Select MOPID From MOPUSER.MOPNOTES Group By MOPID Having Count(*) > 1
  • MOPACTIVITY 中的 MOPID 在 MOPNOTES 上是一对多吗?
  • 如果您提供示例数据和您得到的结果将会很有帮助。
  • 正确,MOPACTIVITY(父母)和 MOPNOTES(儿童)。那么,如何仅将一条子记录发送给父母,而子记录是 MOPNOTES.MOPNOTEDATE 的最新记录?非常感谢您的帮助。

标签: sql oracle select join


【解决方案1】:

尝试分组,并使用最大值:

SELECT MOPACTIVITY.MOPID STRICT,
       TO_CHAR(max(MOPNOTES.MOPNOTEDATE), 'yyyy-mm-dd hh24:mi') "MOPNOTEDATE"
FROM MOPUSER.MOPACTIVITY
INNER JOIN MOPUSER.MOPNOTES ON MOPACTIVITY.MOPID=MOPNOTES.MOPID
GROUP BY MOPACTIVITY.MOPID

【讨论】:

    【解决方案2】:

    如果您只需要来自MOPNOTES 的那些列,那么应该这样做:

    SELECT MOPACTIVITY.MOPID STRICT,
           TO_CHAR(MN.MOPNOTEDATE, 
                  'yyyy-mm-dd hh24:mi') "MOPNOTEDATE"
    FROM MOPUSER.MOPACTIVITY
    INNER JOIN (SELECT MOPID, MAX(MOPNOTEDATE) AS "MOPNOTEDATE"
                FROM MOPUSER.MOPNOTES 
                GROUP BY MOPID) MN
        ON MOPACTIVITY.MOPID=MN.MOPID
    

    【讨论】:

    • 我在 AS 收到一个错误(错误:ORA-00905:缺少关键字)。有什么想法吗?
    • @user2464095 您应该根据您的所有要求提出问题,而不是在收到大量正确答案后将它们添加到 cmets。
    • 我很抱歉拉马克。我当时并没有意识到。我的错。
    【解决方案3】:

    您的评论显着改变了问题。这是您要使用分析函数的地方。这是一个例子:

    SELECT ma.MOPID as STRICT,
           TO_CHAR(mn.MOPNOTEDATE, 'yyyy-mm-dd hh24:mi') as "MOPNOTEDATE"
    FROM MOPUSER.MOPACTIVITY ma INNER JOIN
         (select mn.*,
                 MAX(mn.MOPNOTEDATE) over (partition by mn.MOPID ) as maxMOPNOTEDATE
          from MOPUSER.MOPNOTES mn
         ) mn
        ON ma.MOPID = mn.MOPID and ma.MOPNOTEDATE = mn.maxMOPNOTEDATE;
    

    max()over 的使用使其成为分析函数。这是获取每个MOPID 的最大值。 on 子句只选择匹配最大值的记录。

    请注意,如果存在具有相同最新时间戳的重复项,则将全部包括在内。

    【讨论】:

    • “ma”是干什么用的?我需要用 MOPACTIVITY 代替“ma”吗?和 MOPNOTES 为“mn”?谢谢
    • ma 是一个别名,它允许您定位该表中的列,而无需输入完整的表名。这通常可以使连接和其他列用法更具可读性
    • 那么,如果我想从子表 (MOPNOTES) 向 SELECT 中添加一个字段,我应该将它添加到语句的 INNER JOIN 部分吗?
    • @user2464095 。 . .子查询有mn.*,这意味着它正在从MOPNOTES 表中获取所有列。您可以将任何您喜欢的列放在外部选择中。
    • 谢谢戈登,但我还是很困惑。如果我删除“mn.mopnotes”行,下面的代码就可以工作。我把它放在哪里?我收到错误:ORA-00904: "MN"."MOPNOTE": invalid identifier SELECT MOPACTIVITY.MOPID STRICT, TO_CHAR(MN.MOPNOTEDATE, 'yyyy-mm-dd hh24:mi') "MOPNOTEDATE", MN.MOPNOTE FROM MOPUSER .MOPACTIVITY INNER JOIN (SELECT MOPID, MAX(MOPNOTEDATE) AS "MOPNOTEDATE" FROM MOPUSER.MOPNOTES GROUP BY MOPID) MN ON MOPACTIVITY.MOPID=MN.MOPID
    【解决方案4】:
    SELECT 
        DISTINCT
        MOPACTIVITY.MOPID STRICT,
        TO_CHAR(MOPNOTES.MOPNOTEDATE, 
                  'yyyy-mm-dd hh24:mi') "MOPNOTEDATE"
    FROM MOPUSER.MOPACTIVITY
       INNER JOIN MOPUSER.MOPNOTES 
           ON MOPACTIVITY.MOPID=MOPNOTES.MOPID
    

    尝试使用 Distinct 关键字。

    【讨论】:

    • 如果来自MOPNOTES 的行有不同的日期,这将毫无帮助
    • @Luv 我理解这种情绪,这就是我没有投反对票的原因。但是,它仍然不应该被真正支持,因为它是一个错误的答案。现在,这让操作感到困惑,他们可能会认为(根据她的评论)这是一个解决她的问题的代码,而实际上不是
    • @Luv 我不明白如何,但那好吧。我可能没有正确理解您的问题
    • @user2464095 通过这个查询,你真的会在每个MOPID 中得到一个日期吗?
    • 如果这“真的解决了问题”,那是因为 (a) 每个 MOPID 目前只有一个子行,或者 (b) 所有子行都具有完全相同的时间戳。
    猜你喜欢
    • 2016-10-16
    • 1970-01-01
    • 2016-09-20
    • 2017-08-09
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多