Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
Major Disorder
Starting Member
2 Posts |
Posted - 2003-10-20 : 09:32:49
|
| Hi, After a week of trying everything I know I've resorted to asking you guys for some help. I've got 4 tables (quite a few columns ommited for brevity)1 Users - Name & Id2 Fixture - Fixture Name, Date , League , CreatedBy & Game Type3 Point - Points & Id4 FixtureRace - Records the Result of a Fixture , Race , User & Points scoredWhat I'd like in my query is 1) For each User, the count of entries in the FixtureRaces table for the current month only (showing 0 for no entries) and a sum of the points won (showing 0 for no points)2) This list should be filtered (where'd) by the LeagueId + Date in the Fixture table.I've tried the following query (and numerous variations too):select u.Name , count(fr.RaceId), sum(p.points) from users uleft join FixtureRace fr on fr.userid= u.useridleft join Point p on p.pointid = fr.pointidfull join Fixture f on F.FixtureId = fr.FixtureIdwhere DatePart(month,f.[Date]) = DatePart(month, Getdate())andf.LeagueId = @LeagueIdgroup by u.NameThe problem is that no matter what I've tried I cannot get a full list of users to show with "0" against them......probably really simple for you guys but it's really got me foxed.Hope you can helpthanksPeteThe create scripts for the tables are attached below:if not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Fixture]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) BEGINCREATE TABLE [dbo].[Fixture] ( [FixtureId] [int] IDENTITY (1, 1) NOT NULL , [GameId] [int] NOT NULL , [LeagueId] [int] NOT NULL , [Date] [datetime] NOT NULL CONSTRAINT [DF_Fixture_Date] DEFAULT (getdate()), [CreatedBy] [int] NULL , CONSTRAINT [PK_Fixture] PRIMARY KEY CLUSTERED ( [FixtureId] ) ON [PRIMARY] ) ON [PRIMARY]ENDGOif not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Point]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) BEGINCREATE TABLE [dbo].[Point] ( [PointId] [int] IDENTITY (1, 1) NOT NULL , [Points] [int] NULL , CONSTRAINT [PK_Point] PRIMARY KEY CLUSTERED ( [PointId] ) ON [PRIMARY] ) ON [PRIMARY]ENDGOif not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Users]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) BEGINCREATE TABLE [dbo].[Users] ( [UserId] [int] IDENTITY (1, 1) NOT NULL , [Name] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL , CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED ( [UserId] ) ON [PRIMARY] ) ON [PRIMARY]ENDGOif not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[FixtureRace]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) BEGINCREATE TABLE [dbo].[FixtureRace] ( [FixtureId] [int] NOT NULL , [RaceId] [int] NOT NULL , [UserId] [int] NOT NULL , [PointId] [int] NOT NULL , CONSTRAINT [PK_FixtureRace] PRIMARY KEY CLUSTERED ( [FixtureId], [RaceId], [UserId] ) ON [PRIMARY] , CONSTRAINT [FK_FixtureRace_Fixture] FOREIGN KEY ( [FixtureId] ) REFERENCES [dbo].[Fixture] ( [FixtureId] ), CONSTRAINT [FK_FixtureRace_Point] FOREIGN KEY ( [PointId] ) REFERENCES [dbo].[Point] ( [PointId] ), CONSTRAINT [FK_FixtureRace_Users] FOREIGN KEY ( [UserId] ) REFERENCES [dbo].[Users] ( [UserId] )) ON [PRIMARY]ENDGO |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2003-10-20 : 09:55:09
|
you are taking the wrong approach, break it down:1) first, you want to start with all users. so,SELECT userID from Users2) now, you want to display the count of entries in the fixtures table per user for the current month:SELECT userID, count(*) as FixtureCountFROM FixtureWHERE DatePart(month,f.[Date]) = DatePart(month, Getdate())GROUP BY userID3) and you also want total points per user:SELECT UserID, sum(Points) as TotalPointsFROM FixturePointsGROUP BY USerIDMake sure all 3 queries work the way you want and return proper results. do it all in 3 parts. make sure you are happy. now join them together:SELECT UserID, ISNULL(FixtureCount,0) as FixtureCount, ISNULL(TotalPoints,0) as TotalPointFROM UsersLEFT OUTER JOIN (SQL From part 2) AON A.UserID = Users.UserIDLEFT OUTER JOIN (SQL From part 3) BON B.UserID = Users.UserID Notice the ISNULL() function replaces Nulls with 0. ALWAYS ALWAYS break down queries like this into the smallest part (in this case, everything should be GROUPED by userID) and then put them all together at the end.- Jeff |
 |
|
|
Major Disorder
Starting Member
2 Posts |
Posted - 2003-10-20 : 10:24:03
|
Thanks for that Jeff, I can see I've still got a lot to learn SQL wise..... I've put the lot together for the full solution with a few other bits like the leagueId). To me this seems like quite a complex query, it's going to be on one of the higher hits pages on my site (i think), do you think I will have performance issues?The FixtureRace table has around 1000 entries at the moment and I would guess will grow by about 500 / week when things hot up a bit. I don't have any plans to archive this data so I was wondering would it be sensible to normalise it into a separate "results" table in the medium to long term.Thanks again for your swift reply, that one query had me stuck for weeks SELECT Users.[Name], ISNULL(FixtureCount,0) as FixtureCount, ISNULL(TotalPoints,0) as TotalPointFROM Users LEFT OUTER JOIN (SELECT FR.userID, count(FR.FixtureId) as FixtureCount FROM FixtureRace FR join Fixture F on F.FixtureId = FR.FixtureId WHERE DatePart(month,F.[Date]) = DatePart(month, Getdate()) AND F.LeagueId = 1 GROUP BY FR.userID) A ON A.UserID = Users.UserIDLEFT OUTER JOIN (SELECT UserID, sum(p.Points) as TotalPoints FROM FixtureRace join Point P on P.PointId = FixtureRace.PointId GROUP BY USerID) B ON B.UserID = Users.UserID |
 |
|
|
|
|
|
|
|