数据被多次求和

时间:2014-12-10 22:19:28

标签: sql join sum

以下是我遇到的问题代码。一切都很顺利,直到我为#34; Asian"添加了这条线。这个信息必须来自一个新表,所以我不得不做一个新的联接。一旦我这样做,我开始遇到信息问题。问题是CDS_MailPlayer可以为同一个人拥有多个Mail_ID。然后,它会为每个Mail_ID执行所有Sum,然后将它们全部添加到一起。因此,如果玩家显示100美元的实际值,但有2个邮件ID,则他们的实际值将为200美元。如果他们有10个邮件ID,那么他们的实际价格将飙升至1000美元。

如何添加支票以查看某人的邮件ID是否介于161和166之间,而不会弄乱我的数学?

另外还有一个方法是有一种方法可以将Where子句更改为滚动12个月,这样如果您在2014年12月的任何一天提取报告,它将会拉动12/1 / 2013-11 / 30/2014但是如果您在2015年1月撤消报告,则日期范围将更改为1/1 / 2014-12 / 31/2014。我尽可能地知道如何知道。

一如既往,关于如何清理代码并使其更快/更好的任何建议将不胜感激,这仍然是SQL的新手。

使用SQL Server 2000。

Select P.Player_ID as "Player ID"
    ,Ltrim(RTrim(P.FirstName)) as "First Name"
    ,Ltrim(RTrim(P.LastName)) as "Last Name"
    ,Convert(char(10),cast(P.Birthday as datetime),101) as "Birthday"
    ,P.EMail as "E-Mail"
    ,Ltrim(RTrim(A.City1)) as "City"
    ,Ltrim(RTrim(A.State1)) as"State"
    ,Ltrim(RTrim(A.Zip1)) as "Zip"
    ,A.BadAddress1
    ,A.CustomFlag3 as "Do Not Mail"
    ,P.LL_Dap_Flag
    ,Round(Sum(S.TWin),2) as Theo
    ,Round(((Sum(case when S.StatType = 'Slot' then S.CashIn - S.CashOut - S.JackPot Else 0 end)*.75)+
      (Sum(case when S.StatType = 'Pit' then S.CashIn + S.CreditIn + S.ChipsIn + S.FrontIn - S.CashOut Else 0 end)*.4)),2) as Actual
    ,Count(Distinct(S.GamingDate)) as Trips
    ,Count(Distinct Month(S.GamingDate)) as Month
    ,Count(Distinct case when S.StatType = 'Slot' then S.GamingDate end) as "Slot Trips"
    ,Count(Distinct case when S.StatType = 'Slot' then Month(S.GamingDate) end)as "Slot Month"
    ,Count(Distinct case when S.StatType = 'Pit' then S.GamingDate end) as "Table Trips"
    ,Count(Distinct case when S.StatType = 'Pit' then Month(S.GamingDate) end)as "Table Month"
    ,Round(Sum(S.TWin)/Nullif(Count(Distinct S.GamingDate),0),2) as ADT
    ,Round(sum(S.Twin)/Nullif(count(Distinct Month(S.GamingDate)),0),2) as AMT
    ,Round((((Sum(case when S.StatType = 'Slot' then S.CashIn - S.CashOut - S.JackPot Else 0 end)*.75)+
      (Sum(case when S.StatType = 'Pit' then S.CashIn + S.CreditIn + S.ChipsIn + S.FrontIn - S.CashOut Else 0 end)*.4))/Nullif(Count(Distinct(S.GamingDate)),0)),2) as ADL
    ,Round((((Sum(case when S.StatType = 'Slot' then S.CashIn - S.CashOut - S.JackPot Else 0 end)*.75)+
      (Sum(case when S.StatType = 'Pit' then S.CashIn + S.CreditIn + S.ChipsIn + S.FrontIn - S.CashOut Else 0 end)*.4))/Nullif(Count(Distinct Month (S.GamingDate)),0)),2) as AML
    ,case when Sum(case when S.StatType = 'Pit' then S.TWin Else 0 end)>=(Sum(S.TWin)*.8)then 'Table' else 'Slot' end as "Slot/Table"
    ,case when Sum(case when M.Mail_ID between '161' and '166' then 1 else 0 end)>0 Then 'Y' else 'N' end as "Asian"
    ,Case
        When R.Rank_ID = '1' then 'Silver'
        When R.Rank_ID = '2' then 'Gold'
        When R.Rank_ID = '3' then 'Platinum'
        When R.Rank_ID = '4' then 'Diamond'
        Else 'Copper'
    end as "Rank"
    ,P.HostUser_ID
    ,P.Referral

From  dbo.CDS_ACCOUNT as A
    Join dbo.CDS_PLAYER as P
        on A.[Primary_ID] = P.[Player_ID]
    Join dbo.CDS_STATDAY as S
        on A.[Primary_ID] = S.[Meta_ID]
    Join dbo.CDS_MAILPLAYER as M
        on A.[Primary_ID] = M.Player_ID
    Join dbo.Tiered_Rank_Player as R
        on A.[Primary_ID] = R.Player_ID

Where S.GamingDate >= Dateadd(year,-1,getdate())
      And S.IDType = 'P'
      And S.StatType <> 'Poker'
      And A.CustomFlag1 = 'N'  
      And A.CustomFlag2 = 'N'  
      And A.CustomFlag4 = 'N'  
      And A.CustomFlag5 = 'N'  

Group by P.Player_ID
    ,P.FirstName
    ,P.LastName
    ,P.Birthday
    ,P.EMail
    ,A.City1
    ,A.State1
    ,A.Zip1
    ,A.BadAddress1
    ,A.CustomFlag3
    ,P.LL_Dap_Flag
    ,R.Rank_ID
    ,P.HostUser_ID
    ,P.Referral

我的解决方案如下所示我只是将亚洲人的行更改为子查询,然后从from select语句中删除了关联的join和group by。

Select P.Player_ID as "Player ID"
    ,Ltrim(RTrim(P.FirstName)) as "First Name"
    ,Ltrim(RTrim(P.LastName)) as "Last Name"
    ,Convert(char(10),cast(P.Birthday as datetime),101) as "Birthday"
    ,P.EMail as "E-Mail"
    ,Ltrim(RTrim(A.City1)) as "City"
    ,Ltrim(RTrim(A.State1)) as"State"
    ,Ltrim(RTrim(A.Zip1)) as "Zip"
    ,A.BadAddress1
    ,A.CustomFlag3 as "Do Not Mail"
    ,P.LL_Dap_Flag
    ,Round(Sum(S.TWin),2) as Theo
    ,Round(((Sum(case when S.StatType = 'Slot' then S.CashIn - S.CashOut - S.JackPot Else 0 end)*.75)+
      (Sum(case when S.StatType = 'Pit' then S.CashIn + S.CreditIn + S.ChipsIn + S.FrontIn - S.CashOut Else 0 end)*.4)),2) as Actual
    ,Count(Distinct(S.GamingDate)) as Trips
    ,Count(Distinct Month(S.GamingDate)) as Month
    ,Count(Distinct case when S.StatType = 'Slot' then S.GamingDate end) as "Slot Trips"
    ,Count(Distinct case when S.StatType = 'Slot' then Month(S.GamingDate) end)as "Slot Month"
    ,Count(Distinct case when S.StatType = 'Pit' then S.GamingDate end) as "Table Trips"
    ,Count(Distinct case when S.StatType = 'Pit' then Month(S.GamingDate) end)as "Table Month"
    ,Round(Sum(S.TWin)/Nullif(Count(Distinct S.GamingDate),0),2) as ADT
    ,Round(sum(S.Twin)/Nullif(count(Distinct Month(S.GamingDate)),0),2) as AMT
    ,Round((((Sum(case when S.StatType = 'Slot' then S.CashIn - S.CashOut - S.JackPot Else 0 end)*.75)+
      (Sum(case when S.StatType = 'Pit' then S.CashIn + S.CreditIn + S.ChipsIn + S.FrontIn - S.CashOut Else 0 end)*.4))/Nullif(Count(Distinct(S.GamingDate)),0)),2) as ADL
    ,Round((((Sum(case when S.StatType = 'Slot' then S.CashIn - S.CashOut - S.JackPot Else 0 end)*.75)+
      (Sum(case when S.StatType = 'Pit' then S.CashIn + S.CreditIn + S.ChipsIn + S.FrontIn - S.CashOut Else 0 end)*.4))/Nullif(Count(Distinct Month (S.GamingDate)),0)),2) as AML
    ,case when Sum(case when S.StatType = 'Pit' then S.TWin Else 0 end)>=(Sum(S.TWin)*.8)then 'Table' else 'Slot' end as "Slot/Table"
    ,(Select case when Sum(case when M.Mail_ID between '161' and '166' then 1 else 0 end)>0 Then 'Y' else 'N' end as "Asian"
        From dbo.CDS_MAILPLAYER as M) as "Asian"
    ,Case
        When R.Rank_ID = '1' then 'Silver'
        When R.Rank_ID = '2' then 'Gold'
        When R.Rank_ID = '3' then 'Platinum'
        When R.Rank_ID = '4' then 'Diamond'
        Else 'Copper'
    end as "Rank"
    ,P.HostUser_ID
    ,P.Referral

From  dbo.CDS_ACCOUNT as A
    Join dbo.CDS_PLAYER as P
        on A.[Primary_ID] = P.[Player_ID]
    Join dbo.CDS_STATDAY as S
        on A.[Primary_ID] = S.[Meta_ID]
    Join dbo.Tiered_Rank_Player as R
        on A.[Primary_ID] = R.Player_ID

Where S.GamingDate between '12/1/2013' and '11/30/2014'
      And S.IDType = 'P'
      And S.StatType <> 'Poker'
      And A.CustomFlag1 = 'N'  
      And A.CustomFlag2 = 'N'  
      And A.CustomFlag4 = 'N'  
      And A.CustomFlag5 = 'N'  

Group by P.Player_ID
    ,P.FirstName
    ,P.LastName
    ,P.Birthday
    ,P.EMail
    ,A.City1
    ,A.State1
    ,A.Zip1
    ,A.BadAddress1
    ,A.CustomFlag3
    ,P.LL_Dap_Flag
    ,R.Rank_ID
    ,P.HostUser_ID
    ,P.Referral
    ,P.Casino_ID

2 个答案:

答案 0 :(得分:1)

尝试以下三个小修改来解决您的主要问题:

1)在选择部分:

,case when isnull(M.Mail_ID_sp,0) = 0 Then 'N' else 'Y' end as "Asian"

2)在表连接部分:

 left outer Join (SELECT Player_ID, count(*) as Mail_ID_sp FROM dbo.CDS_MAILPLAYER where M.Mail_ID between '161' and '166' GROUP BY Player_ID ) as M 

3)最后平衡group by子句:

,case when isnull(M.Mail_ID_sp,0) = 0 Then 'N' else 'Y' end -- Balancing Group By

答案 1 :(得分:0)

在我找到回答我自己的问题的按钮之前,我用我最后使用的答案更新了原始问题。