【问题标题】:Inner Join returning redundant data and not the expected data内部联接返回冗余数据而不是预期数据
【发布时间】:2016-10-08 19:20:46
【问题描述】:

我有以下查询-

 SELECT CP.PostID,CP.SectionID                              
     FROM NewsLetter NW  
     inner Join MapNewsletterPosts as MM on NW.ID = MM.ID        
     inner join CSPosts as CP with (nolock) on MM.PostID = CP.PostID       
     inner join PostStatus PS on PS.Postid=CP.PostId      
     WHERE  
     NW.NewsletterDate = '2015-07-06' 
     and CP.IsApproved =1                                           
     ANd PS.StatusId =7      
     AND CP.SectionID NOT IN (92,227)        
     AND NW.SectionID = 95
     ORDER BY MM.Newslettersortorder 

上面的查询返回正确的结果如下图-

现在,当我在上述查询中再添加一个连接时 -

SELECT CP.PostID,CP.SectionID                                
     FROM NewsLetter NW    
     inner Join MapNewsletterPosts as MM on NW.ID = MM.ID          
     inner join CSPosts as CP with (nolock) on MM.PostID = CP.PostID         
     inner join PostStatus PS on PS.Postid=CP.PostId      
     INNER JOIN NewsletterDetails ND ON ND.NewsletterDate = NW.NewsletterDate AND ND.IncludeInArticles=1 <<--added extra JOIN   
     WHERE    
     NW.NewsletterDate = '2015-07-06'   
     and CP.IsApproved =1                                             
     ANd PS.StatusId =7        
     AND CP.SectionID NOT IN (92,227)          
     AND NW.SectionID = 95  
     ORDER BY MM.Newslettersortorder 

导致数据冗余如下图-

我需要在查询中进行哪些更改才能返回正确的结果 [不同]。 提前谢谢...!!

【问题讨论】:

标签: sql sql-server sql-server-2008 join distinct


【解决方案1】:

您可以用EXISTS() 替换额外的连接:

 SELECT CP.PostID,CP.SectionID                              
 FROM NewsLetter NW  
 inner Join MapNewsletterPosts as MM on NW.ID = MM.ID        
 inner join CSPosts as CP with (nolock) on MM.PostID = CP.PostID       
 inner join PostStatus PS on PS.Postid=CP.PostId      
 WHERE EXISTS(SELECT 1 FROM NewsletterDetails nd
              WHERE ND.NewsletterDate = NW.NewsletterDate AND ND.IncludeInArticles=1)
      AND NW.NewsletterDate = '2015-07-06' 
      and CP.IsApproved =1                                           
      ANd PS.StatusId =7      
      AND CP.SectionID NOT IN (92,227)        
      AND NW.SectionID = 95
 ORDER BY MM.Newslettersortorder 

发生这种情况是因为额外表中有超过 1 行具有相同的 NewsletterDate,存在将消除这种情况,您将不再需要使用 DISTINCTGROUP BY

编辑:如果您只想要那些不存在带有IncludeInArticles=0 的记录的记录,那么使用这个:

 SELECT CP.PostID,CP.SectionID                              
 FROM NewsLetter NW  
 inner Join MapNewsletterPosts as MM on NW.ID = MM.ID        
 inner join CSPosts as CP with (nolock) on MM.PostID = CP.PostID       
 inner join PostStatus PS on PS.Postid=CP.PostId      
 WHERE NOT EXISTS(SELECT 1 FROM NewsletterDetails nd
                  WHERE ND.NewsletterDate = NW.NewsletterDate AND ND.IncludeInArticles=0)
      AND NW.NewsletterDate = '2015-07-06' 
      and CP.IsApproved =1                                           
      ANd PS.StatusId =7      
      AND CP.SectionID NOT IN (92,227)        
      AND NW.SectionID = 95
 ORDER BY MM.Newslettersortorder 

编辑:很难理解你到底想要什么!我猜你想要有 IncludeInArticles = 1 而没有 IncludeInArticles=0 的记录?现在这是唯一的选择:

 SELECT CP.PostID,CP.SectionID                              
 FROM NewsLetter NW  
 inner Join MapNewsletterPosts as MM on NW.ID = MM.ID        
 inner join CSPosts as CP with (nolock) on MM.PostID = CP.PostID       
 inner join PostStatus PS on PS.Postid=CP.PostId      
 WHERE EXISTS(SELECT 1 FROM NewsletterDetails nd
              WHERE ND.NewsletterDate = NW.NewsletterDate AND ND.IncludeInArticles=1)
   AND NOT EXISTS(SELECT 1 FROM NewsletterDetails nd
                  WHERE ND.NewsletterDate = NW.NewsletterDate AND ND.IncludeInArticles=0)
      AND NW.NewsletterDate = '2015-07-06' 
      and CP.IsApproved =1                                           
      ANd PS.StatusId =7      
      AND CP.SectionID NOT IN (92,227)        
      AND NW.SectionID = 95
 ORDER BY MM.Newslettersortorder 

【讨论】:

  • 我已经检查了您的查询,但条件 ND.IncludeInArticles=1 不起作用它正在返回具有 ND.IncludeInArticles=0 的行
  • 等一下,您只想要ND.IncludeInArticles=0 行不存在的行吗? @PranavBilurkar
  • 错过理解我想要具有ND.IncludeInArticles=1的行
  • @Pranav Bilurkar:我认为您需要更好地解释加入NewsletterDetails意图。目前尚不清楚您想用它来完成什么,因此答案各不相同。
  • @PranavBilurkar 那么这个查询应该可以工作!可能有 ND.IncludeInArticles=1ND.IncludeInArticles=0 的记录,这就是它令人困惑的原因
【解决方案2】:

您可以将ON 条件替换为ND.PostId =CP.PostID

试试这个 -

SELECT CP.PostID,CP.SectionID                                
     FROM NewsLetter NW    
     inner Join MapNewsletterPosts as MM on NW.ID = MM.ID          
     inner join CSPosts as CP with (nolock) on MM.PostID = CP.PostID         
     inner join PostStatus PS on PS.Postid=CP.PostId      
     INNER JOIN NewsletterDetails ND ON ND.PostId =CP.PostID AND ND.IncludeInArticles=1    
     WHERE    
     NW.NewsletterDate = '2015-07-06'   
     and CP.IsApproved =1                                             
     ANd PS.StatusId =7        
     AND CP.SectionID NOT IN (92,227)          
     AND NW.SectionID = 95  
     ORDER BY MM.Newslettersortorder 

【讨论】:

    【解决方案3】:

    最终的内部连接将有每个 PostID 的多行数据。

    返回第一组结果的最简单方法是将 distinct 修饰符添加到选择:

    SELECT DISTINCT CP.PostID,CP.SectionID
    

    【讨论】:

      【解决方案4】:

      发生这种情况的原因是 NewsLetterDetails 中有多行数据。尝试将此表中的一个字段拉入您的查询中,以了解我的意思。

       SELECT 
           CP.PostID
           ,CP.SectionID 
           ,ND.*                            
       FROM NewsLetter NW    
       INNER JOIN MapNewsletterPosts as MM 
           ON NW.ID = MM.ID          
       INNER JOIN CSPosts as CP with (nolock) 
           ON MM.PostID = CP.PostID         
       INNER JOIN PostStatus PS 
           ON PS.Postid=CP.PostId      
       INNER JOIN NewsletterDetails ND 
           ON ND.NewsletterDate = NW.NewsletterDate 
           AND ND.IncludeInArticles=1    
       WHERE NW.NewsletterDate = '2015-07-06'   
           AND CP.IsApproved =1                                             
           AND PS.StatusId =7        
           AND CP.SectionID NOT IN (92,227)          
           AND NW.SectionID = 95  
       ORDER BY MM.Newslettersortorder 
      

      如果您只是想要一个像以前一样的唯一列表,请执行此操作;

       SELECT DISTINCT
           CP.PostID
           ,CP.SectionID 
       FROM NewsLetter NW    
       INNER JOIN MapNewsletterPosts as MM 
           ON NW.ID = MM.ID          
       INNER JOIN CSPosts as CP with (nolock) 
           ON MM.PostID = CP.PostID         
       INNER JOIN PostStatus PS 
           ON PS.Postid=CP.PostId      
       INNER JOIN NewsletterDetails ND 
           ON ND.NewsletterDate = NW.NewsletterDate 
           AND ND.IncludeInArticles=1    
       WHERE NW.NewsletterDate = '2015-07-06'   
           AND CP.IsApproved =1                                             
           AND PS.StatusId =7        
           AND CP.SectionID NOT IN (92,227)          
           AND NW.SectionID = 95  
       ORDER BY MM.Newslettersortorder 
      

      【讨论】:

      • 但是,我不想从 NewsletterDetails 中选择任何内容...查询应该只返回 PostIDSectionID
      • 我创建了第一个查询来解释为什么您会看到意想不到的数据。如果您只想要一个不同的列表,请使用我的答案中的第二个查询。
      • 如果指定了 SELECT DISTINCT,则 ORDER BY 项目必须出现在选择列表中。 - 第二个查询
      • 您需要按该字段订购吗?我看不出有任何理由。
      • 听起来@sagi 有你想要的答案,这是处理它的好方法。
      猜你喜欢
      • 1970-01-01
      • 2010-09-20
      • 1970-01-01
      • 1970-01-01
      • 2014-07-23
      • 2014-08-28
      • 2020-09-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多