2010-07-17 118 views
2

我的查询总是产生重复的结果。如何使用数据库> 100万行解决此查询的最佳做法。SQL查询产生重复行,我看不出为什么

Select segstart 
    ,segment 
    ,callid 
    ,Interval 
    ,dialed_num 
    ,FiscalMonthYear 
    ,SegStart_Date 
    ,row_date 
    ,Name 
    ,Xferto 
    ,TransferType 
    ,Agent 
    ,Sup 
    ,Manager 
    ,'MyCenter' = Case Center 
When 'Livermore Call Center' Then 'LCC' 
When 'Natomas Call Center' Then 'NCC' 
When 'Concord Call Center' Then 'CCC' 
When 'Virtual Call Center' Then 'VCC' 
When 'Morgan Hill Call Center' Then 'MHCC' 
Else Center 
End 
    ,Xferfrom 
    ,talktime 
    ,ANDREWSTABLE.transferred 
    ,ANDREWSTABLE.disposition 
    ,dispsplit 
    ,callid 
    ,hsplit.starttime 
    ,CASE 
    WHEN hsplit.callsoffered > 0 
    THEN (CAST(hsplit.acceptable as DECIMAL)/hsplit.callsoffered)*100 
    ELSE '0' 
    END AS 'Service Level' 
    ,hsplit.callsoffered 
    ,hsplit.acceptable 
FROM 
(
Select segstart, 
    100*DATEPART(HOUR, segstart) + 30*(DATEPART(MINUTE, segstart)/30) as Interval, 
    FiscalMonthYear, 
    SegStart_Date, 
    dialed_num, 
    callid, 
    Name, 
    t.Queue AS 'Xferto', 
    TransferType, 
    RepLName+', '+RepFName AS Agent, 
    SupLName+', '+SupFName AS Sup, 
    MgrLName+', '+MgrFName AS Manager, 
    q.Center, 
    q.Queue AS 'Xferfrom', 
    e.anslogin, 
    e.origlogin, 
    t.Extension, 
    transferred, 
    disposition, 
    talktime, 
    dispsplit, 
    segment 
From CMS_ECH.dbo.CaliforniaECH e 

INNER JOIN Cal_RemReporting.dbo.TransferVDNs t on e.dialed_num = t.Extension 
INNER JOIN InfoQuest.dbo.IQ_Employee_Profiles_v3_AvayaId q on e.origlogin = q.AvayaID 
INNER JOIN Cal_RemReporting.dbo.udFiscalMonthTable f on e.SegStart_Date = f.Tdate 

Where SegStart_Date between getdate()-90 and getdate()-1 
    And q.Center not in ('Collections Center', 
         'Cable Store', 
         'Business Services Center', 
         'Escalations') 
    And SegStart_Date between RepToSup_StartDate and RepToSup_EndDate 
    And SegStart_Date between SupToMgr_StartDate and SupToMgr_EndDate 
    And SegStart_Date between Avaya_StartDate and Avaya_EndDate 
    And SegStart_Date between RepQueue_StartDate and RepQueue_EndDate 
    AND (e.transferred like '1' 
    OR e.disposition like '4') order by segstart 
) AS ANDREWSTABLE 

--Left Join CMS_ECH.dbo.hsplit hsplit on hsplit.starttime = ANDREWSTABLE.Interval and hsplit.row_date = ANDREWSTABLE.SegStart_Date and ANDREWSTABLE.dispsplit = hsplit.split 

回答

6

有两种possibities:

  1. 有在您的系统的多个记录将出现在您的结果集,产生重复的行,因为你的投影不会选择sufficent列来区分它们或您的where子句中没有按”不要过滤它们。
  2. 由于ON子句不完整,您的连接会生成虚假重复项。

这两种情况只能由具备必要的领域知识水平的人解决。所以我们不打算为你解决这个问题。抱歉。

你需要做的是将一些重复的结果与一些不重复的结果进行comapare比较,并发现第一组的共同之处,这也与第二组有区别。

我不是说这很容易,尤其是数百万行。但如果这很容易,那就不值得去做。

+0

你能解释ON子句是如何不完整的吗? – CodingIsAwesome 2010-07-17 05:38:32

+4

@CodingAwesome - 当ON子句不识别唯一键时,它们将产生交叉连接。如果其中一个表具有复合键,并且我们没有指定其所有列或者如果我们连接到不是唯一键的列,则可能会发生这种情况。 – APC 2010-07-17 05:48:23

3

我已经进入了几次我自己,它总是最终成为我的联合声明之一。我会尝试一次删除一条连接语句,并查看是否删除其中的一条减少了重复条目的数量。

另一种选择是找到一组重复的行并查询连接值中的连接中的每个表并查看返回的结果。

此外,您正在运行什么数据库和什么版本?