Hi, I am having access data given in input.xls format and i am using cross tab query to get output in form of output.xls.I am using query given below.Its working fine but taking time to execute.So,can anyone tell me how to modify query to get faster result.
Query:
TRANSFORM Last(rate) AS sumRating SELECT symbol FROM (SELECT Time,Rate,Symbol, IIF(Time>=#10:00:00 AM# and Time<#11:00:00 AM#,IIF(Time<#10:10:00 AM#,'10:00:00-10:10:00', IIF(Time<#10:20:00 AM#,'10:10:01-10:20:00', IIF(Time<#10:30:00 AM#,'10:20:01-10:30:00', IIF(Time<#10:40:00 AM#,'10:30:01-10:40:00' ,IIF( time<#10:50:00 AM#,'10:40:01-10:50:00','10:50:01-11:00:00') )))), IIF(Time>=#11:00:00 AM# and Time<#12:00:00 PM#,IIF(Time<#11:10:00 AM#,'11:00:01-11:10:00', IIF(Time<#11:20:00 AM#,'11:10:01-11:20:00', IIF(Time<#11:30:00 AM#,'11:20:01-11:30:00', IIF(Time<#11:40:00 AM#,'11:30:01-11:40:00' ,IIF( time<#11:50:00 AM#,'11:40:01-11:50:00','11:50:01-12:00:00') )))) ,IIF(Time>=#12:00:00 PM# and Time<#1:00:00 PM#,IIF(Time<#12:10:00 PM#,'12:00:01-12:10:00', IIF( Time<#12:20:00 PM#,'12:10:01-12:20:00', IIF(Time<#12:30:00 PM#,'12:20:01-12:30:00', IIF( Time<#12:40:00 PM#,'12:30:01-12:40:00' ,IIF( time<#12:50:00 PM#,'12:40:01-12:50:00','12:50:01-1:00:00') )))) ,IIF(Time>=#1:00:00 PM# and Time<#2:00:00 PM#,IIF( Time<#1:10:00 PM#,'1:00:01-1:10:00', IIF( Time<#1:20:00 PM#,'1:10:01-1:20:00', IIF( Time<#1:30:00 PM#,'1:20:01-12:30:00', IIF( Time<#1:40:00 PM#,'1:30:01-1:40:00' ,IIF( time<#1:50:00 PM#,'1:40:01-1:50:00','1:50:01-2:00:00') )))) ,IIF(Time>=#2:00:00 PM# and Time<#3:00:00 PM#,IIF(Time<#2:10:00 PM#,'2:00:01-12:10:00', IIF(Time<#2:20:00 PM#,'2:10:01-2:20:00', IIF(Time<#2:30:00 PM#,'2:20:01-2:30:00', IIF(Time<#2:40:00 PM#,'2:30:01-2:40:00' ,IIF( time<#2:50:00 PM#,'2:40:01-2:50:00','2:50:01-3:00:00') )))) ,IIF(Time>=#3:00:00 PM#,IIF( Time<#3:10:00 PM#,'3:00:01-3:10:00', IIF(Time<#3:20:00 PM#,'3:10:01-3:20:00', IIF(Time<#3:30:00 PM#,'3:20:01-3:30:00', IIF( Time<#3:40:00 PM#,'3:30:01-3:40:00' ,IIF( time<#3:50:00 PM#,'3:40:01-3:50:00') )))) ,'NONE'))))))As period from broadcast where symbol='TCS' or symbol='DLF' or symbol='SUMMIT' ) GROUP BY symbol PIVOT Period;
I want to display lastest rate for every script on interval of 10 minutes.
IIF is not taking time.........i tried to run only inner query where i am using IIF,its not taking much time.Cross tab query is taking much time........i think bcas number of columns are more in crosstab query its taking time
and one more thing while i am using excel vba to get result from Ms-Access ,i am not able to receive column name along with data?Do you have any idea about it
TRANSFORM Last(B.Rate) SELECT B.Symbol FROM broadcast AS B GROUP BY B.Symbol PIVOT CDate(Int(B.Time*144)/144);
That is, no answer at all, because Last() does not what you expect it to do. Last gives you any one value from the group -- the last encountered, and there is no syntax to specify which order you want to apply for the Last() function.
In other words, your query will get even slower by several orders of magnitude. For example, this is correct but terribly slow:
SELECT B.Time, B.Symbol, B.Rate FROM broadcast AS B WHERE Not Exists ( Select True From broadcast Where Symbol=B.Symbol And Time > B.Time And Time < (Int(B.Time*144)+1)/144 );
Even with indexes on Symbol and Time, the calculation hurts the query, and nothing gets optimized. Instead, you can add a new field:
Slice: Number, Integer; Indexed
And run this:
UPDATE broadcast AS B SET B.Slice = Int(B.Time*144);
If needed, the equivalent time is: CDate(Slice/144) to CDate((Slice+1)/144). With all three indexes (on Symbol, Slice, and Time), this is reasonably fast:
SELECT B.Time, B.Slice, B.Symbol, B.Rate FROM broadcast AS B WHERE Not Exists ( Select True From broadcast Where Symbol=B.Symbol And Slice = B.Slice And Time > B.Time );
However, it uses a sub-query, so that it can't serve as source for a cross-tab. That's one of the annoying limitations of Jet SQL. You can now either use a make-table query and use the new table as source, or run a second update query, for the new field LastInS: Yes/No
UPDATE broadcast SET LastInS = False;
UPDATE broadcast AS B SET B.LastInS = True WHERE Not Exists ( Select True From broadcast Where Symbol=B.Symbol And Slice = B.Slice And Time > B.Time );
LastInS indicates which records we want to see (113 among the 8888 you showed us). And now we have a fast cross-tab, for example:
TRANSFORM First(B.Rate) SELECT B.Symbol FROM broadcast AS B WHERE B.LastInS GROUP BY B.Symbol PIVOT CDate(B.Slice/144) & '-' & CDate((B.Slice+1)/144);
or (looks better and is even faster)
TRANSFORM First(B.Rate) SELECT CDate(B.Slice/144) AS [From], CDate((B.Slice+1)/144) AS [To] FROM broadcast AS B WHERE B.LastInS GROUP BY B.Slice PIVOT B.Symbol;
I am going to use this query after every 10-15 minutes .So, if i use make table query,so many tables will be generated.And then i am suppose to write query to delete table first,then again to create table (Copy of source),then cross tab query on new table.Dont u think it will take much time?
In that case, work only with the latest data. Keep track of the time you run the procedure and limit your queries to only the "time slices" that can still change.
If you added the fields Slice and LastInS, run the first update query for only "Slice Is Null" and the second for only "Slice >= (the corresponding number)". It will be even faster. But the update queries are already quite fast, and you probably tested the cross-tab: it's now almost instantaneous, isn't it?
Do not use the make-table query, as that would force you to regenerate the entire table every time, and it can't be faster than the update query.