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.

 All Forums
 SQL Server 2000 Forums
 SQL Server Development (2000)
 Defaults in Cross Tab Query

Author  Topic 

AskSQLTeam
Ask SQLTeam Question

0 Posts

Posted - 2006-04-06 : 20:05:02
Dion writes "Hi,
I am using SQL Server 2000 on Win 2k and writing reports to be displayed in Crystal Reports 10. I have a design issue with an application with regard to a cross tab query.

Schema Structure
The application writes audit data to a daily log table with the following basic structure. (The data is normalised out but for the purposes of this I will show it as a single structure)

DlDate DATETIME
DlName VARCHAR(24)
DlMachineName VARCHAR(12)
DlMachineFunction VARCHAR(12)
....
....

I am writing some views which will be used for reporting access that will provide a hook into the base tables. I need to generate a cross tab report with each hour of the day on the left and the number of transactions against each machine function. It should look something like....

ENTRY EXIT PAYMENT
00:00 00:59 0 0 0
01:00 01:59 1 0 0
...
...
23:00 23:59 4 3 9

My reporting view uses the CASE statement to add a column against each row which is the hour that the transaction occurred. My view is:

SELECT DlDate,
'Hour' =
CASE
WHEN (DATEPART(hour,dl.DlDate)*60)+(DATEPART(minute,dl.DlDate)) <= 59 THEN 1
WHEN WHEN ((DATEPART(hour,dl.DlDate)*60)+(DATEPART(minute,dl.DlDate)) > 59) AND ((DATEPART(hour,dl.DlDate)*60)+(DATEPART(minute,dl.DlDate)) <= 119) THEN 2
....
....
ELSE 99
END,
DlName,DlMachineName,DlMachineFunction

So far this all looked good however if the data in the base table does not include any transactions for hours 10 or 21 (for example) this is not included in the output from the query. I need to find a design/solution that will populate all 24 hours for each MachineFunction if the base table does not include a transaction during this period.

I have experiemented with the use of UNION and UNION ALL but I think on large volumes of data the query will perform badly.

I hope I have explained this clearly and that someone from this community can show me the error or my ways.

Many Thanks
Dave"

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2006-04-06 : 21:44:26
use a hour table to left join to your table.

See below for illustration
declare	@hour table ( hr int )

declare @data table ( hr int, value int)

insert into @data(hr, value)
select 1, 10 union all select 2, 20 union all
select 4, 40 union all select 5, 50 union all
select 6, 60

declare @i int

select @i = 0
while (@i < 24)
begin
insert into @hour select @i
select @i = @i + 1
end

select * from @data

hr value
----------- -----------
1 10
2 20
4 40
5 50
6 60

(5 row(s) affected)


select h.hr, isnull(d.value, 0) as val
from @hour h left join @data d
on h.hr = d.hr

hr val
----------- -----------
0 0
1 10
2 20
3 0
4 40
5 50
6 60
7 0
8 0
9 0
10 0
11 0
12 0
13 0
14 0
15 0
16 0
17 0
18 0
19 0
20 0
21 0
22 0
23 0

(24 row(s) affected)





KH


Go to Top of Page

brizzle
Starting Member

1 Post

Posted - 2006-04-07 : 09:25:34
Hi Khtan,

That worked a treat...

Thanks
Go to Top of Page
   

- Advertisement -