Group by或Subquery无法确定是否能解决问题

时间:2015-01-12 15:35:10

标签: sql-server subquery sql-server-2000

下面是我尝试使用的代码,但它希望我将S.Gamingdate添加到Group By。当我这样做时,每个玩家每天都会得到一排结果。我需要为每位玩家提供一整天的总结。我尝试在case语句中添加一个总和,并将转换中的总和移到case语句之外,看看是否会有所帮助,但事实并非如此。我想我将不得不使用子查询,但因为我对SQL很陌生,所以我之前不必使用子查询,并且希望得到一些帮助。

使用SQL Server 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

1 个答案:

答案 0 :(得分:1)

重写[3个月ADT]和[6个月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 - 如果它返回0,您将得到一个被零除错误。

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

我创建了一个完整的脚本,任何人都可以在空数据库中运行。首先,在取消[3个月ADT]和[6个月ADT]的表达式后,我认为你要做的是获得平均播放日期的TWin?在这种情况下,只需使用AVG功能 - 它将忽略NULL(未播放的日期)。注意S.TWin前面的1.0 * - 如果你的TWin是一个整数,它会把它转换成一个小数,这样AVG的结果也是十进制的。另请注意LEFT JOIN到dbo.CDS_STATDAY - 这可以防止没有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

希望这有帮助。

里斯