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 2005 Forums
 Transact-SQL (2005)
 Fix a query

Author  Topic 

Sunny155
Starting Member

15 Posts

Posted - 2009-03-31 : 14:19:10
Hi guys, I am new here. I need help fixing a query or maybe need advise to write it diffrenetly.

I have 5 tables in a database - Transactions, Product, Service, ServProvider and GlbServiceD.

I want to query the transaction, product, service, servprovidet table based on unique id of service table. Service table has got 8 records so 8 ids. I want to insert the result of the qury into 5th table.


The query is like this (The joins are self explanatory)-

DECLARE @LoopID as int

DECLARE @MaxLoopID as int

SET @LoopId = 1

SET @MaxLoopID = (SELECT Max(nid) FROM dbo.service WHERE nid <> 1000)

WHILE @LoopID <= @MaxLoopID

BEGIN

INSERT INTO dbo.GlbServiceD

SELECT getdate()-1 as dDay, Min(@LoopID) as nServiceID, count(T.sOpType) as nTransaction, sum(T.nValue) as nCashinFlow , sum(T.nRevenue) as nRevenue1

FROM dbo.Transactions AS T

INNER JOIN

dbo.Product AS P ON T.nProductID = P.nID

INNER JOIN

dbo.ServProvider AS SP ON P.nServProvID = SP.nID

INNER JOIN

dbo.Service AS S ON SP.nServiceID = S.nID

WHERE T.sOptype = 'transaction' and datediff(day, T.dInsertion, getdate()-1) = 0 AND T.nErrorCodeId = 0 AND S.nID = @LoopID

SET @LoopID = @LoopID+1

END;


The select results this value if no records match -

dDay = 2009-03-30 23:08:26.700 - (sample)
nServiceID = NULL ----- (PLEASE NOTE)
nTransaction = 0
nCashinFlow = NULL
nRevenue1 = NULL

A picture says thousand words -
Screenshot of the query (Removed INSERT INTO to show u the result)

http://img90.imageshack.us/my.php?image=captureaoq.jpg

actuallu i want to set the value of nServiceID to the id of service id which is currently in loop (like if id 1 is in loop than 1, 2 than 2) and insert 8 records (bcos service table has 8 records)

So the fixed qury will do something like this -

Record 1 (where data found and not null )

dDay = 2009-03-30 23:08:26.700 - (sample)
nServiceID = 1
nTransaction = 5
nCashinFlow = 100
nRevenue1 = 1000

Record 2 (where data not found hence null)

dDay = 2009-03-30 23:08:26.700 - (sample)
nServiceID = 2 ----- (PLEASE NOTE)
nTransaction = 0
nCashinFlow = NULL
nRevenue1 = NULL

Record 3 (where data not found hence null)

dDay = 2009-03-30 23:08:26.700 - (sample)
nServiceID = 3 ----- (PLEASE NOTE)
nTransaction = 0
nCashinFlow = NULL
nRevenue1 = NULL


Record 4 (where data found and not null)

dDay = 2009-03-30 23:08:26.700 - (sample)
nServiceID = 4
nTransaction = 3
nCashinFlow = 600
nRevenue1 = 2000

and etc upto total 8 records

please help fix this qury or suggest a new one.
PS - I intend to use this query in conjunction with Scheduler and SQL Server Job so making it as stored procedure a good idea?

Bustaz Kool
Master Smack Fu Yak Hacker

1834 Posts

Posted - 2009-03-31 : 15:12:34
without the data I can't see why your query is returning empty data. My first question is, "Why are you using a loop?" Would this approach get you the proper results:

INSERT INTO dbo.GlbServiceD
SELECT getdate()-1 as dDay, S.nID as nServiceID, count(T.sOpType) as nTransaction, sum(T.nValue) as nCashinFlow , sum(T.nRevenue) as nRevenue1
FROM dbo.Transactions AS T
INNER JOIN
dbo.Product AS P ON T.nProductID = P.nID
INNER JOIN
dbo.ServProvider AS SP ON P.nServProvID = SP.nID
INNER JOIN
dbo.Service AS S ON SP.nServiceID = S.nID
WHERE T.sOptype = 'transaction'
and datediff(day, T.dInsertion, getdate()-1) = 0
AND T.nErrorCodeId = 0
GROUP BY S.nID

As for your PS question, I like all data access to be from within the database so I prefer the stored procedure approach. That way, I can always search the database for references to the tables and not have to worry that there is some ad hoc query hidden in an application or package that is going to bite me later.


=======================================
Men build too many walls and not enough bridges. -Isaac Newton, philosopher and mathematician (1642-1727)
Go to Top of Page

Sunny155
Starting Member

15 Posts

Posted - 2009-03-31 : 15:51:46
Actually i am not very experienced in sql programming like this.
I ran your query but it does not produce the result at all if theres no match. I require it should produce result like 2009-03-31,1,0,NULL,NULL and vice versa if theres no match. (see my post above for more details) It should insert 8 recorrds bcos theres currently 8 recrods in service table.
My requirement is to insert data in GlbServiceD table by querying transactions table based on service id.
The query will accomplish this report - Global by service by day  

Columns in GlbServiceD -
nId; dDay; nTransaction; nProviderId; nCashInFlow; nRevenue1 

I need 1 record created for each service id match.

I am providing sample data for 4 tables in csv format.

http://rapidshare.com/files/215875420/Sample_Data.zip.html
Go to Top of Page

Sunny155
Starting Member

15 Posts

Posted - 2009-03-31 : 16:30:52
In short and simple terms if the query doesnt matches data i still want empty columns with querying filter (service id from service table)and date to be inserted in GlbServiceD table.
Go to Top of Page

Vinnie881
Master Smack Fu Yak Hacker

1231 Posts

Posted - 2009-03-31 : 17:01:55
I didn't spend much time looking at this, but try the below query.

INSERT INTO dbo.GlbServiceD
SELECT getdate()-1 as dDay, t.nID as nServiceID, count(T.sOpType) as nTransaction, sum(T.nValue) as nCashinFlow , sum(T.nRevenue) as nRevenue1
FROM dbo.Transactions AS T
Left JOIN
dbo.Product AS P ON T.nProductID = P.nID
Left JOIN
dbo.ServProvider AS SP ON P.nServProvID = SP.nID
Left JOIN
dbo.Service AS S ON SP.nServiceID = S.nID
WHERE T.sOptype = 'transaction'
and datediff(day, T.dInsertion, getdate()-1) = 0
AND T.nErrorCodeId = 0
GROUP BY t.nID




Success is 10% Intelligence, 70% Determination, and 22% Stupidity.
\_/ _/ _/\_/ _/\_/ _/ _/- 881
Go to Top of Page

Sunny155
Starting Member

15 Posts

Posted - 2009-03-31 : 23:40:12
no its the same query that @Bustaz Kool suggested me. Pls see my reply to him and suggest a way to me. It wont take you much time as you guys are experienced.
Go to Top of Page

Vinnie881
Master Smack Fu Yak Hacker

1231 Posts

Posted - 2009-04-01 : 00:01:13
There's a very important differance between that my query and what Bustaz sugested.

The "Left Join"'s rather then the "Inner join"'s will allow the query to still return null values when their are no existing records in the linked table.


Success is 10% Intelligence, 70% Determination, and 22% Stupidity.
\_/ _/ _/\_/ _/\_/ _/ _/- 881
Go to Top of Page

Sunny155
Starting Member

15 Posts

Posted - 2009-04-01 : 10:29:30
Sorry i didnt saw it in a hurry. I am blind. he he
Your query didnt worked.
Go to Top of Page

Vinnie881
Master Smack Fu Yak Hacker

1231 Posts

Posted - 2009-04-01 : 12:29:07
I think I'm following what you want.

You need a # table, I have included in the code a function to provide that written by Michael Valentine Jones. try running the query bellow, basically it will link to a # table (In a final version it would be better to keep a # table in your database, it's a handy table to have), but you can obviously tweak to fit your needs

SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
if exists
(select * from dbo.sysobjects
where id = object_id(N'[dbo].[F_TABLE_NUMBER_RANGE]')
and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[F_TABLE_NUMBER_RANGE]
GO
create function dbo.F_TABLE_NUMBER_RANGE
(
@START_NUMBER int,
@END_NUMBER int
)
/*
This function returns an integer table containing all integers
in the range of@START_NUMBER through @END_NUMBER, inclusive.
The maximum number of rows that this function can return
is 16777216.
*/

returns table
as

return
(
select top 100 percent
NUMBER = (a.NUMBER+b.NUMBER)+
-- Add the starting number for the final result set
-- The case is needed, because the start and end
-- numbers can be passed in any order
case
when @START_NUMBER <= @END_NUMBER
then @START_NUMBER
else @END_NUMBER
end
from
(
Select top 100 percent
NUMBER = convert(int,N01+N02+N03)
From
-- Cross rows from 3 tables based on powers of 16
-- Maximum number of rows from cross join is 4096, 0 to 4095
( select N01 = 0 union all select 1 union all select 2 union all
select 3 union all select 4 union all select 5 union all
select 6 union all select 7 union all select 8 union all
select 9 union all select 10 union all select 11 union all
select 12 union all select 13 union all select 14 union all
select 15 ) n01
cross join
( select N02 = 0 union all select 16 union all select 32 union all
select 48 union all select 64 union all select 80 union all
select 96 union all select 112 union all select 128 union all
select 144 union all select 160 union all select 176 union all
select 192 union all select 208 union all select 224 union all
select 240 ) n02
cross join
( select N03 = 0 union all select 256 union all select 512 union all
select 768 union all select 1024 union all select 1280 union all
select 1536 union all select 1792 union all select 2048 union all
select 2304 union all select 2560 union all select 2816 union all
select 3072 union all select 3328 union all select 3584 union all
select 3840 ) n03
where
-- Minimize the number of rows crossed by selecting only rows
-- with a value less the the square root of rows needed.
N01+N02+N03 <
-- Square root of total rows rounded up to next whole number
convert(int,ceiling(sqrt(abs(@START_NUMBER-@END_NUMBER)+1)))
order by
1
) a
cross join
(
Select top 100 percent
NUMBER =
convert(int,
(N01+N02+N03) *
-- Square root of total rows rounded up to next whole number
convert(int,ceiling(sqrt(abs(@START_NUMBER-@END_NUMBER)+1)))
)
From
-- Cross rows from 3 tables based on powers of 16
-- Maximum number of rows from cross join is 4096, 0 to 4095
( select N01 = 0 union all select 1 union all select 2 union all
select 3 union all select 4 union all select 5 union all
select 6 union all select 7 union all select 8 union all
select 9 union all select 10 union all select 11 union all
select 12 union all select 13 union all select 14 union all
select 15 ) n01
cross join
( select N02 = 0 union all select 16 union all select 32 union all
select 48 union all select 64 union all select 80 union all
select 96 union all select 112 union all select 128 union all
select 144 union all select 160 union all select 176 union all
select 192 union all select 208 union all select 224 union all
select 240 ) n02
cross join
( select N03 = 0 union all select 256 union all select 512 union all
select 768 union all select 1024 union all select 1280 union all
select 1536 union all select 1792 union all select 2048 union all
select 2304 union all select 2560 union all select 2816 union all
select 3072 union all select 3328 union all select 3584 union all
select 3840 ) n03
where
-- Minimize the number of rows crossed by selecting only rows
-- with a value less the the square root of rows needed.
N01+N02+N03 <
-- Square root of total rows rounded up to next whole number
convert(int,ceiling(sqrt(abs(@START_NUMBER-@END_NUMBER)+1)))
order by
1
) b
where
a.NUMBER+b.NUMBER <
-- Total number of rows
abs(@START_NUMBER-@END_NUMBER)+1 and
-- Check that the number of rows to be returned
-- is less than or equal to the maximum of 16777216
case
when abs(@START_NUMBER-@END_NUMBER)+1 <= 16777216
then 1
else 0
end = 1
order by
1
)

GO
GRANT SELECT ON [dbo].[F_TABLE_NUMBER_RANGE] TO [public]
GO

-- Demo using the function to ruturn numbers 1 to 2000
DECLARE @MaxLoopID as int
SET @MaxLoopID = (SELECT Max(nid) FROM dbo.service WHERE nid <> 1000)

INSERT INTO dbo.GlbServiceD
SELECT getdate()-1 as dDay, aa.Number as nServiceID, count(T.sOpType) as nTransaction, sum(T.nValue) as nCashinFlow , sum(T.nRevenue) as nRevenue1
FROM
dbo.F_TABLE_NUMBER_RANGE(1,@MaxLoopID) aa
Left Join
dbo.Transactions AS T
on aa.Number = t.NID
Left JOIN
dbo.Product AS P ON T.nProductID = P.nID
Left JOIN
dbo.ServProvider AS SP ON P.nServProvID = SP.nID
Left JOIN
dbo.Service AS S ON SP.nServiceID = S.nID
WHERE T.sOptype = 'transaction'
and datediff(day, T.dInsertion, getdate()-1) = 0
AND T.nErrorCodeId = 0
GROUP BY aa.Number



Success is 10% Intelligence, 70% Determination, and 22% Stupidity.
\_/ _/ _/\_/ _/\_/ _/ _/- 881
Go to Top of Page

Sunny155
Starting Member

15 Posts

Posted - 2009-04-02 : 07:25:30
WOW thata a massive query. I will reply as sooon as i test it. Thanks @Vinnie for taking pain for my sql query. he he
Go to Top of Page
   

- Advertisement -