【问题标题】:SQL - why is this 'where' needed to remove row duplicates, when I'm already grouping?SQL - 当我已经分组时,为什么需要删除行重复项?
【发布时间】:2013-06-16 18:47:29
【问题描述】:
  • 为什么在此查询中需要最后一个“WHERE”子句来限制重复项?
  • 第一个 LEFT JOIN 将程序链接到 UID 上的实体
  • 第一个 INNER JOIN 将程序链接到子查询,该子查询通过链接 UID 来获取这些程序的统计信息
  • 子查询(获取 StatsForDistributorClubs 子集)正在对 UID 列进行分组
  • 所以,我本以为无论如何这都会加入唯一记录,所以我们不应该得到行重复
  • 那么为什么需要通过确保“程序”链接到“实体”来基于最终的 WHERE 进行限制?

(为清楚起见,省略了查询的无关部分)

SELECT  LmiEntity.[DisplayName]
        ,StatsForDistributorClubs.*
FROM    [Program]
LEFT JOIN
        LMIEntityProgram
ON      LMIEntityProgram.ProgramUid = Program.ProgramUid
INNER JOIN
(
    SELECT  e.LmiEntityUid,
            sp.ProgramUid,
            SUM(attendeecount) [Total attendance],

        FROM    LMIEntity e,
                Timetable t,
                TimetableOccurrence [to],
                ScheduledProgramOccurrence spo,
                ScheduledProgram sp
        WHERE   
                t.LicenseeUid = e.lmientityUid
        AND     [to].TimetableOccurrenceUid = spo.TimetableOccurrenceUid
        AND     sp.ScheduledProgramUid = spo.ScheduledProgramUid

        GROUP BY e.lmientityUid, sp.ProgramUid
    ) AS StatsForDistributorClubs
ON Program.ProgramUid = StatsForDistributorClubs.ProgramUid
INNER JOIN LmiEntity
ON LmiEntity.LmiEntityUid = StatsForDistributorClubs.LmiEntityUid
LEFT OUTER JOIN Region
ON Region.RegionId = LMIEntity.RegionId
WHERE (
       [Program].LicenseeUid = LmiEntity.LmiEntityUid 
       OR
       [LMIEntityProgram].LMIEntityUid = LmiEntity.LmiEntityUid 
      )

【问题讨论】:

    标签: sql join group-by where-clause duplicate-removal


    【解决方案1】:

    如果您在外部查询中进行分组,则可能不需要额外的条件,但只会对您的内部查询进行分组。您对分组内部查询的 LEFT JOIN 仍然可能导致返回多条记录,因此您的任何 JOIN 都可能是罪魁祸首。

    如果没有看到重复的样本,很难知道重复的来源,但是外部查询上的 GROUPING 肯定会删除完整的重复,或者修改后的 JOIN 标准可以解决它。

    【讨论】:

    • 谢谢 - 这是一个很好的观点,并缩小了原因。我将给这个答案,因为期望任何人在没有访问数据的情况下指出这一点是不合理的,我无法提供这些数据
    【解决方案2】:

    您在结果集中有: 选择 LmiEntity。[显示名称] ,StatsForDistributorClubs.*

    我想你的复制来自 LMIEntityProgram。

    我的猜想:LMIEntityProgram - 是一个同时具有 LmiEntityId 和 ProgramId 的桥表,但您只能通过 ProgramId 加入。

    如果单个 ProgramId 有多个 LmiEntityId - 你必须有重复。

    这会重复你在 WHERE 中过滤:

     [LMIEntityProgram].LMIEntityUid = LmiEntity.LmiEntityUid 
    

    你可以在 JOIN 中做到这一点:

     LEFT JOIN LMIEntityProgram
        ON LMIEntityProgram.ProgramUid = Program.ProgramUid
            AND [LMIEntityProgram].LMIEntityUid = LmiEntity.LmiEntityUid    
    

    【讨论】:

    • 感谢 Ingaz,但是我链接的是 ProgramUID 而不是 ProgramId,因此应该只有一个唯一的“程序”记录。这不是重复的来源。感谢您的意见 - 无论如何我都支持您,因为您的建议很容易就是这种情况
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多