Group by 或 Subquery 帮助不确定是否会解决问题

Either Group by or Subquery help not sure will fix the issue

下面是我尝试使用的代码,但它希望我将 S.Gamingdate 添加到分组依据。当我这样做时,我会得到每个玩家每天玩的一排结果。我只需要为每个玩家总结所有日子的一行。我尝试在 case 语句周围添加一个总和,并将总和从 cast 移到 case 语句之外,看看是否有帮助,但没有用。我在想我将不得不进行子查询,但由于我是 SQL 的新手,所以我之前没有进行过子查询,希望得到一些帮助。

使用 SQL 服务器 2000

Select P.Player_ID
,P.FirstName
,P.LastName
,P.HostUser_ID
,A.HomePhone1
,P.EMail
,A.City1
,M.Miles
,Case when S.GamingDate between '10/1/2014' and '12/31/2014' then Cast(Sum(S.TWin)/Nullif(Count(Distinct S.GamingDate),0) as Decimal (18,2)) Else 0 End) as "3 Month ADT"
,Case when S.GamingDate between '7/1/2014' and '12/31/2014' then Cast(Sum(S.TWin)/Nullif(Count(Distinct S.GamingDate),0) as Decimal (18,2)) Else 0 End) as "6 Month ADT"

From dbo.CDS_ACCOUNT as A
    Join dbo.CDS_Player as P
        on A.Account_ID = P.Player_ID
    Join dbo.CDS_STATDAY as S
        on A.Account_ID = Meta_ID
    Join dbo.Player_Miles as M
        on A.Account_ID = M.Player_ID

Group by P.Player_ID
,P.FirstName
,P.LastName
,P.HostUser_ID
,A.HomePhone1
,P.EMail
,A.City1
,M.Miles

重写 [3 Month ADT] 和 [6 Month ADT] 的表达式,使 SUM 中包含 S.GamingDate。没有模式,我无法测试它,但像这样的东西应该可以解决问题;

Cast(Sum(Case when S.GamingDate between '10/1/2014' and '12/31/2014' then S.TWin else null end)/Nullif(Count(Distinct S.GamingDate),0) as Decimal (18,2))) as "3 Month ADT"

此外,您可能需要删除 NULLIF - 如果它曾经 returns 0,您将得到被零除的错误。

编辑以提供更多信息和完整的工作脚本;

我已经创建了一个完整的脚本,任何人都可以在空数据库中 运行。首先,在取消选择 [3 Month ADT] 和 [6 Month ADT] 的表达式后,我认为您想要做的是获取播放日期的平均 TWin?在这种情况下,只需使用 AVG 函数 - 它会忽略 NULL(未播放的日期)。请注意 S.TWin 前面的 1.0 * - 如果您的 TWin 是整数,这会将其转换为小数,以便 AVG 的结果也是小数。另请注意 dbo.CDS_STATDAY 的 LEFT JOIN - 这可防止未在 dbo.CDS_STATDAY 中输入的玩家从结果中消失。

如果我不太明白你要做什么,请告诉我。

/*
-- Schema script to create some dummy tables and data

create table dbo.CDS_ACCOUNT (
    Account_ID int,
    HomePhone1 varchar(20),
    City1 varchar(20)
)
create table dbo.CDS_Player (
    Player_ID int,
    FirstName varchar(20),
    LastName varchar(20),
    HostUser_ID int,
    EMail  varchar(20)
)
create table dbo.CDS_STATDAY (
    Meta_ID int,
    GamingDate date,
    TWin int
)
create table dbo.Player_Miles (
    Player_ID int,
    Miles int
)
go

set nocount on
insert dbo.CDS_ACCOUNT values (1,'Phone1','City1')
insert dbo.CDS_ACCOUNT values (2,'Phone2','City2')
insert dbo.CDS_ACCOUNT values (3,'Phone3','City3')
insert dbo.CDS_ACCOUNT values (4,'Phone4','City4')

insert dbo.CDS_Player values (1, 'Tom','Alas',101,'Email1')
insert dbo.CDS_Player values (2, 'Dick','Smith',102,'Email2')
insert dbo.CDS_Player values (3, 'Harry','Jones',103,'Email3')
insert dbo.CDS_Player values (4, 'Han','Solo',104,'Email4')

insert dbo.CDS_STATDAY values (1,'2014-01-01',10)
insert dbo.CDS_STATDAY values (1,'2014-11-01',10)
insert dbo.CDS_STATDAY values (2,'2014-01-01',9)
insert dbo.CDS_STATDAY values (2,'2014-09-01',9)
insert dbo.CDS_STATDAY values (2,'2014-11-01',10)
insert dbo.CDS_STATDAY values (3,'2014-01-01',9)
insert dbo.CDS_STATDAY values (3,'2014-07-01',9)
insert dbo.CDS_STATDAY values (3,'2014-09-01',10)
insert dbo.CDS_STATDAY values (3,'2014-11-01',11)

insert dbo.Player_Miles values (1, 50)
insert dbo.Player_Miles values (2, 60)
insert dbo.Player_Miles values (3, 70)
insert dbo.Player_Miles values (4, 80)
go
*/

Select P.Player_ID
,P.FirstName
,P.LastName
,P.HostUser_ID
,A.HomePhone1
,P.EMail
,A.City1
,M.Miles
,avg(Case when S.GamingDate between '10/1/2014' and '12/31/2014' then 1.0 * S.TWin else null end) as "3 Month ADT"
,avg(Case when S.GamingDate between '7/1/2014' and '12/31/2014' then 1.0 * S.TWin else null end) as "6 Month ADT"

From dbo.CDS_ACCOUNT as A
    Join dbo.CDS_Player as P
        on A.Account_ID = P.Player_ID
    Left Join dbo.CDS_STATDAY as S
        on A.Account_ID = Meta_ID
    Join dbo.Player_Miles as M
        on A.Account_ID = M.Player_ID

Group by P.Player_ID
,P.FirstName
,P.LastName
,P.HostUser_ID
,A.HomePhone1
,P.EMail
,A.City1
,M.Miles

希望对您有所帮助。

里斯