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 |
|
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 intDECLARE @MaxLoopID as intSET @LoopId = 1SET @MaxLoopID = (SELECT Max(nid) FROM dbo.service WHERE nid <> 1000)WHILE @LoopID <= @MaxLoopIDBEGININSERT INTO dbo.GlbServiceDSELECT 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 TINNER JOINdbo.Product AS P ON T.nProductID = P.nIDINNER JOINdbo.ServProvider AS SP ON P.nServProvID = SP.nIDINNER JOINdbo.Service AS S ON SP.nServiceID = S.nIDWHERE T.sOptype = 'transaction' and datediff(day, T.dInsertion, getdate()-1) = 0 AND T.nErrorCodeId = 0 AND S.nID = @LoopIDSET @LoopID = @LoopID+1END; The select results this value if no records match -dDay = 2009-03-30 23:08:26.700 - (sample)nServiceID = NULL ----- (PLEASE NOTE)nTransaction = 0nCashinFlow = NULLnRevenue1 = NULLA picture says thousand words -Screenshot of the query (Removed INSERT INTO to show u the result)http://img90.imageshack.us/my.php?image=captureaoq.jpgactuallu 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 = 5nCashinFlow = 100nRevenue1 = 1000Record 2 (where data not found hence null)dDay = 2009-03-30 23:08:26.700 - (sample)nServiceID = 2 ----- (PLEASE NOTE)nTransaction = 0nCashinFlow = NULLnRevenue1 = NULLRecord 3 (where data not found hence null)dDay = 2009-03-30 23:08:26.700 - (sample)nServiceID = 3 ----- (PLEASE NOTE)nTransaction = 0nCashinFlow = NULLnRevenue1 = NULLRecord 4 (where data found and not null)dDay = 2009-03-30 23:08:26.700 - (sample)nServiceID = 4nTransaction = 3nCashinFlow = 600nRevenue1 = 2000and etc upto total 8 recordsplease 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.GlbServiceDSELECT 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 TINNER JOINdbo.Product AS P ON T.nProductID = P.nIDINNER JOINdbo.ServProvider AS SP ON P.nServProvID = SP.nIDINNER JOINdbo.Service AS S ON SP.nServiceID = S.nIDWHERE T.sOptype = 'transaction' and datediff(day, T.dInsertion, getdate()-1) = 0 AND T.nErrorCodeId = 0GROUP BY S.nIDAs 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) |
 |
|
|
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 |
 |
|
|
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. |
 |
|
|
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.GlbServiceDSELECT 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 TLeft JOINdbo.Product AS P ON T.nProductID = P.nIDLeft JOINdbo.ServProvider AS SP ON P.nServProvID = SP.nIDLeft JOINdbo.Service AS S ON SP.nServiceID = S.nIDWHERE T.sOptype = 'transaction' and datediff(day, T.dInsertion, getdate()-1) = 0 AND T.nErrorCodeId = 0GROUP BY t.nID Success is 10% Intelligence, 70% Determination, and 22% Stupidity.\_/ _/ _/\_/ _/\_/ _/ _/- 881 |
 |
|
|
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. |
 |
|
|
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 |
 |
|
|
Sunny155
Starting Member
15 Posts |
Posted - 2009-04-01 : 10:29:30
|
| Sorry i didnt saw it in a hurry. I am blind. he heYour query didnt worked. |
 |
|
|
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 needsSET QUOTED_IDENTIFIER ON GOSET ANSI_NULLS ON GOif exists (select * from dbo.sysobjectswhere 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]GOcreate function dbo.F_TABLE_NUMBER_RANGE( @START_NUMBER int, @END_NUMBER int)/*This function returns an integer table containing all integersin the range of@START_NUMBER through @END_NUMBER, inclusive.The maximum number of rows that this function can returnis 16777216.*/returns table asreturn(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 endfrom ( 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 ) bwhere 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 = 1order by 1)GOGRANT SELECT ON [dbo].[F_TABLE_NUMBER_RANGE] TO [public]GO-- Demo using the function to ruturn numbers 1 to 2000DECLARE @MaxLoopID as intSET @MaxLoopID = (SELECT Max(nid) FROM dbo.service WHERE nid <> 1000)INSERT INTO dbo.GlbServiceDSELECT 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) aaLeft Joindbo.Transactions AS Ton aa.Number = t.NIDLeft JOINdbo.Product AS P ON T.nProductID = P.nIDLeft JOINdbo.ServProvider AS SP ON P.nServProvID = SP.nIDLeft JOINdbo.Service AS S ON SP.nServiceID = S.nIDWHERE T.sOptype = 'transaction' and datediff(day, T.dInsertion, getdate()-1) = 0 AND T.nErrorCodeId = 0GROUP BY aa.Number Success is 10% Intelligence, 70% Determination, and 22% Stupidity.\_/ _/ _/\_/ _/\_/ _/ _/- 881 |
 |
|
|
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 |
 |
|
|
|
|
|
|
|