【问题标题】:How to eliminate duplicate rows joining on tables across databases?如何消除跨数据库表连接的重复行?
【发布时间】:2013-05-08 15:09:06
【问题描述】:

我已经在这个脚本上工作了一段时间,但已经走到了死胡同。该脚本有效,但不幸的是产生了重复。我的脚本在 state_issue_teacher_id 键上跨数据库连接两个不同的表,然后生成输出。我检查了两个表并且行数相同,并且连接应该与记录完美匹配,但显然我的键或我加入表的方式存在问题,并且我的输出返回部分不正确。我还尝试连接属性以创建唯一键并加入表,但仍然产生不正确的结果。

这是我的脚本:

SELECT     
       LTRIM(RTRIM(rt.year_time)) AS 'year_time' ,
       LTRIM(RTRIM(rt.state_issue_teacher_id)) AS state_issue_teacher_id ,
       LTRIM(RTRIM(rt.district_code)) AS district_code ,
       rt.district_name ,
       rt.school_name ,
       LTRIM(RTRIM(rt.assignment_code)) AS assignment_code ,
       rt.assignment_desc ,
       LTRIM(RTRIM(rt.position_code)) AS position_code ,
       rt.position_desc ,
       LTRIM(RTRIM(rt.last_name)) AS last_name ,
       LTRIM(RTRIM(rt.first_name)) AS first_name ,
       LTRIM(RTRIM(rt.total_salary)) AS total_salary ,
       rt.assign_fte ,
       LTRIM(RTRIM(rt.school_code)) AS school_code ,
       rt.fte

    FROM    staging.dbo.rt AS rt

    LEFT JOIN ( SELECT   LTRIM(RTRIM(dti.year)) AS year ,
                    LTRIM(RTRIM(dt.teacher_id)) AS teacher_id ,
                    LTRIM(RTRIM(db.district_code)) AS district_code ,
                    db.district_name ,
                    LTRIM(RTRIM(dt.last_name)) AS last_name ,
                    LTRIM(RTRIM(dt.first_name)) AS first_name ,
                    LTRIM(RTRIM(da.assignment_code)) AS assignment_code ,
                    LTRIM(RTRIM(dp.position_code)) AS position_code ,
                    dre.race_ethnicity_code ,
                    LTRIM(RTRIM(SUBSTRING(db.school_code,10,4))) AS school_code ,
                    da.assignment_desc ,
                    dp.position_desc ,
                    fs.total_fte

           FROM     mart.dbo.fact_s AS fs
                    LEFT OUTER JOIN mart.dbo.fact_s.dbo.dim_building
                    AS db ON fs.building_key = db.building_key
                    LEFT OUTER JOIN mart.dbo.fact_s.dbo.dim_teacher
                    AS dt ON fs.teacher_key = dt.teacher_key
                    LEFT OUTER JOIN mart.dbo.fact_s.dbo.dim_assignment
                    AS da ON fs.assignment_key = da.assignment_key
                    LEFT OUTER JOIN mart.dbo.fact_s.dbo.dim_race_ethnicity
                    AS dre ON dt.race_ethnicity_key = dre.race_ethnicity_key
                    LEFT OUTER JOIN mart.dbo.fact_s.dbo.dim_gender
                    AS dg ON dt.gender_key = dg.gender_key
                    LEFT OUTER JOIN mart.dbo.fact_s.dbo.dim_time
                    AS dti ON fs.time_key = dti.time_key
                    LEFT OUTER JOIN mart.dbo.fact_s.dbo.dim_position
                    AS dp ON fs.position_key = dp.position_key
           WHERE    dti.year = '2012'



         ) raw ON    rt.state_issue_teacher_id = raw.teacher_id                 
                        AND rt.year_time = raw.year 
                        AND rt.last_name = raw.last_name 
                        AND rt.first_name = raw.first_name 
                        AND rt.district_code = raw.district_code
                        AND rt.position_code = raw.position_code
                        AND rt.school_code = RAW.school_code
                        AND rt.assignment_code = raw.assignment_code



    WHERE   rt.year_time = '2012'



    ORDER BY rt.last_name, rt.first_name

我得到的输出是:

组合教师作业的 fte 应加起来为 1。但具有相同 assignment_code/desc 且有多个部分作业的教师会产生重复作业。示例:Jane Doe 出现 4 次,总 fte 为 2.0,而不是 2 次,总 fte 为 1.0。输出应如下所示。

【问题讨论】:

  • 所以你不想要从 staging.dbo.rt AS rt, mart.dbo.fact_s AS fs WHERE rt.state_issue_teacher_id = fs.teacher_id AND rt 这样的东西。 year_time = fs.year AND rt.year_time = '2012';
  • 两张表的主键是什么? (相同的行数并不能保证生成的连接也有相同的行数。)
  • Pk 是 state_issue_teacher_id

标签: sql sql-server subquery outer-join


【解决方案1】:

您似乎收到了具有多项作业的兼职教师的副本,作业的所有描述都相同。从实际输出的前四行与所需输出的前两行可以清楚地看出这一点。

我想知道你为什么要从一开始就有这些重复项。然而,他们在事实表中,所以肯定有一些重要的事情(我想资助两名兼职辅导员而不是一名全职辅导员)。在这种情况下,事实表真的有精确的重复记录吗?否则,未重复的字段可能会建议使用额外的连接键来解决问题。

你需要去掉这个连接条件产生的笛卡尔积:rt.assignment_code = raw.assignment_code

除了找到更好的连接键之外,我还可以想出两种方法来解决这个问题。第一个是为职位创建一个真正唯一的 id。也许在您的数据结构中您知道一个。或者,您可以使用row_number() 为拥有多个职位的人员添加序列号。

另一种方法是消除一侧或另一侧的重复项。例如,您可以聚合 rt 以消除此类重复。

【讨论】:

  • Gordon 这些重复项在事实表或临时表中不存在,而 mart 和 fact 的正确结果具有多个分配。并且在任何一个表中都没有更好的唯一连接键。这是整个数据验证过程的一部分,我试图避免操纵原始源文件。我尝试将多个属性连接在一起以获得额外的连接键,但确实收到了相同的重复错误。
  • @Tone 。 . .我观察到,当分配描述相同时,您会得到笛卡尔积,但当它们不同时则不会。最简单的解释是这些行在两边重复,由分配代码连接,还有一些其他的遗漏:要么是显式键,要么是隐式键(可能是因为数据库的设计没有考虑一个人有多个相同的任务)。
猜你喜欢
  • 2015-02-04
  • 1970-01-01
  • 1970-01-01
  • 2011-03-25
  • 1970-01-01
  • 2012-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多