Ask a Question related to Microsoft SQL / MS SQL Server, Design and Development.
-
Tommy #1
Query, Join on nearest
Hello, I am in a position where i need to create a query where i must join
two tables on the nearest value.
Imagine i have 2 tables, tbl_Trade and tbl_Time. For each Time in tbl_Time,
I need to locate the row in tbl_Trade where tbl_Time.LastUpdate is closest
to, but less than the value of tbl_Time.myTime.
I have been using the followng query
Select Avg(s.Price) AS Price , t.myTime
From tbl_Trade s
Inner Join tbl_Times t
On (t.myDate + '2003-07-08') > s.LastUpdate
AND (t.myDate + '2003-07-08' - '1:00 AM') < s.LastUpdate
Inner Join tbl_StockList l
On l.ID = s.StockID
Where l.Code = 'ORI'
Group By t.myTime
But this relies on using an average of all trades in the time period (which
in this case is 1 hour).
Essentially the problem is that each trade can occur at any time, so there
is not necessarily a trade that occurs in that period, nor is an average of
the value of the average of the prices necessarily indicative of the value
we wish to retrieve.
So basically what i want to be able to do is to generate a recordset of the
value of the price of the last trade at each hour O, O is specified in a
table. Is such a join possible? Or is there a work around aside from using
triggers to populate a table of prices for each hour for each commodity?
Cheers
Tommy Guest
-
sql join query
Hi, I have a little problem that's driving me nuts, I'm sure there's a simple solution that I'm overlooking. The problem is this (I'm giving... -
Inner Join Query
Hello Everyone, it's been ages since I posted here, but I just don't get table joins. The background, I am working with an Access db. There are... -
Add another join to a query
I need to add to the SELECT item "C.CATEGORY_ID" to the following query (another join?): Category_id is a column of table "blog_categories" which... -
INNER JOIN query question
I have 2 tables with the following columns (other data fields omitted for brevity): cases.caseid cases.uid profiles.uid profiles.locationid... -
SQL join query help
I have written a forum and am using the following query to search in it: $query="select topics.tid,f_messages.messid from f_messages left join... -
David Portas #2
Re: Query, Join on nearest
Please post DDL (CREATE TABLE statements) and sample data (INSERT
statements).
--
David Portas
------------
Please reply only to the newsgroup
--
David Portas Guest
-
Ray Higdon #3
Query, Join on nearest
I would do it using a full outer join and then specify
the "closeness" in the where statement using datediff.
example where datediff(hh,datecolumn1,datecolumn2) <= 1
HTH
Ray Higdon MCSE, MCDBA, CCNA
where i must join>-----Original Message-----
>Hello, I am in a position where i need to create a queryeach Time in tbl_Time,>two tables on the nearest value.
>
>Imagine i have 2 tables, tbl_Trade and tbl_Time. Fortbl_Time.LastUpdate is closest>I need to locate the row in tbl_Trade wheres.LastUpdate>to, but less than the value of tbl_Time.myTime.
>
>I have been using the followng query
>
>Select Avg(s.Price) AS Price , t.myTime
> From tbl_Trade s
> Inner Join tbl_Times t
> On (t.myDate + '2003-07-08') > s.LastUpdate
> AND (t.myDate + '2003-07-08' - '1:00 AM') <time period (which> Inner Join tbl_StockList l
> On l.ID = s.StockID
> Where l.Code = 'ORI'
> Group By t.myTime
>
>But this relies on using an average of all trades in theany time, so there>in this case is 1 hour).
>
>Essentially the problem is that each trade can occur atnor is an average of>is not necessarily a trade that occurs in that period,indicative of the value>the value of the average of the prices necessarilya recordset of the>we wish to retrieve.
>
>So basically what i want to be able to do is to generatespecified in a>value of the price of the last trade at each hour O, O isaround aside from using>table. Is such a join possible? Or is there a workeach commodity?>triggers to populate a table of prices for each hour for>
>Cheers
>
>
>.
>Ray Higdon Guest
-
John Gilson #4
Re: Query, Join on nearest
"Tommy" <blah@blah.com> wrote in message
news:3f0c03a9$0$59955$c30e37c6@lon-reader.news.telstra.net...Here's a stab at what I believe you're asking, however, without DDL,> Hello, I am in a position where i need to create a query where i must join
> two tables on the nearest value.
>
> Imagine i have 2 tables, tbl_Trade and tbl_Time. For each Time in tbl_Time,
> I need to locate the row in tbl_Trade where tbl_Time.LastUpdate is closest
> to, but less than the value of tbl_Time.myTime.
>
> I have been using the followng query
>
> Select Avg(s.Price) AS Price , t.myTime
> From tbl_Trade s
> Inner Join tbl_Times t
> On (t.myDate + '2003-07-08') > s.LastUpdate
> AND (t.myDate + '2003-07-08' - '1:00 AM') < s.LastUpdate
> Inner Join tbl_StockList l
> On l.ID = s.StockID
> Where l.Code = 'ORI'
> Group By t.myTime
>
> But this relies on using an average of all trades in the time period (which
> in this case is 1 hour).
>
> Essentially the problem is that each trade can occur at any time, so there
> is not necessarily a trade that occurs in that period, nor is an average of
> the value of the average of the prices necessarily indicative of the value
> we wish to retrieve.
>
> So basically what i want to be able to do is to generate a recordset of the
> value of the price of the last trade at each hour O, O is specified in a
> table. Is such a join possible? Or is there a work around aside from using
> triggers to populate a table of prices for each hour for each commodity?
>
> Cheers
sample data, and an example of what the query should return, this is
just a guess.
-- For each stock, give the most recent trade before a given
-- reference time
CREATE VIEW MostRecentTradeAtTime (stock_id, ref_time, actual_time)
AS
SELECT ST.StockID, T.myTime, ST.LastUpdate
FROM tbl_Time AS T
INNER JOIN
tbl_Trade AS ST
ON ST.LastUpdate < T.myTime AND
NOT EXISTS (SELECT *
FROM tbl_Trade
WHERE StockID = ST.StockID AND
LastUpdate > ST.LastUpdate AND
LastUpdate < T.myTime)
Regards,
jag
John Gilson Guest
-
Tommy #5
Re: Query, Join on nearest - My Results
I have spent the better part of the afternoon pissfarting around with this
problem and have come up with 2 different solutions. One uses cursors and
is incredibly fast, the other doesnt and is very slow.
I created them as stored procedures so that i could stress test each more
easily.
The first solution, and nicest looking one is....
---------------------------------------------------------------------------
Create procedure Tester2 (@Stockid as int)
As
Select tbl_Stocks.Price, tbl_Stocks.LastUpdate
From tbl_Stocks
Inner Join (
Select Max(s.ID) AS Closest --, l.Code, s.LastUpdate
From tbl_Stocks s
Inner Join tbl_Times t
On s.LastUpdate < (t.myDate + '2003-07-08')
Where s.StockID=@StockID
Group By t.myDate
) dt_Updates
On dt_Updates.Closest = tbl_Stocks.ID
The second, uglier one is...
---------------------------------------------------------------------------
Create procedure Tester1 (@Stockid as int)
As
declare @myTime as smalldatetime
declare @Result Table ( Price int, LastUpdate smalldatetime )
Declare Time_Cursor cursor
For
Select myDate + '2003-07-08' From tbl_Times
Open Time_Cursor
Fetch Next From Time_Cursor Into @myTime
While @@Fetch_Status = 0
Begin
Insert Into @Result
Select Top 1 Price, LastUpdate
From tbl_Stocks
Where StockID=@StockID
And LastUpdate < @myTime
Order By LastUpdate Desc
Fetch Next From Time_Cursor Into @myTime
End
Close Time_Cursor
Deallocate Time_Cursor
Select * From @Result
---------------------------------------------------------------------------
And the results?
I used a silly little bit of SQL to run each 100 times.
Tester1 1 Second
Tester2 148 Seconds
Running Tester1 1000 Times however took 14 seconds, however i think most of
this was spent in network congestion as the CPU's on the server didnt go
over 30%. Tester2 however was using over 80%. So it seems that Tester1
around 100 times faster (which is a pretty nice speed increase really!)...
Also of note, my earlier incarnations of Tester2 (ie the single query
approach) were taking over 20 seconds per SINGLE query.
In this test case, tbl_Stocks has over 2 million records and tbl_Times has
9. The server is a Dual P4 2.4 Xeon, 1GB Ram. The data created from the
queries is going to form the basis for charts.
I hope this is of interest to some of you.
Cheers!
"Tommy" <blah@blah.com> wrote in message
news:3f0c03a9$0$59955$c30e37c6@lon-reader.news.telstra.net...join> Hello, I am in a position where i need to create a query where i musttbl_Time,> two tables on the nearest value.
>
> Imagine i have 2 tables, tbl_Trade and tbl_Time. For each Time in(which> I need to locate the row in tbl_Trade where tbl_Time.LastUpdate is closest
> to, but less than the value of tbl_Time.myTime.
>
> I have been using the followng query
>
> Select Avg(s.Price) AS Price , t.myTime
> From tbl_Trade s
> Inner Join tbl_Times t
> On (t.myDate + '2003-07-08') > s.LastUpdate
> AND (t.myDate + '2003-07-08' - '1:00 AM') < s.LastUpdate
> Inner Join tbl_StockList l
> On l.ID = s.StockID
> Where l.Code = 'ORI'
> Group By t.myTime
>
> But this relies on using an average of all trades in the time periodof> in this case is 1 hour).
>
> Essentially the problem is that each trade can occur at any time, so there
> is not necessarily a trade that occurs in that period, nor is an averagethe> the value of the average of the prices necessarily indicative of the value
> we wish to retrieve.
>
> So basically what i want to be able to do is to generate a recordset ofusing> value of the price of the last trade at each hour O, O is specified in a
> table. Is such a join possible? Or is there a work around aside from> triggers to populate a table of prices for each hour for each commodity?
>
> Cheers
>
>
Tommy Guest
-
Gert-Jan Strik #6
Re: Query, Join on nearest - My Results
Tommy,
I assume that table tblStocks has a clustered unique index on (StockID,
LastUpdate). If not, then that could help. I also assume that LastUpdate
is of datatype datetime (not smalldatetime). Make sure that @StockID has
the same datatype as column StockID.
How does the query below perform?
Declare @d datetime
Set @d='2003-07-08'
SELECT DateAdd(day,myDate,@d) AS ProbeDate,(
SELECT S2.Price
FROM tblStocks S2
WHERE S2.StockID = @StockID
AND S2.LastUpdate = (
SELECT MAX(S1.LastUpdate)
FROM tblStocks S1
WHERE S1.StockID = @StockID
AND S1.LastUpdate < DateAdd(day,myDate,@d)
)
) AS Price,(
SELECT MAX(LastUpdate)
FROM tblStocks S3
WHERE S3.StockID = @StockID
AND S3.LastUpdate < DateAdd(day,myDate,@d)
) AS LastUpdate
FROM tbl_Times
Gert-Jan
Tommy wrote:>
> I have spent the better part of the afternoon pissfarting around with this
> problem and have come up with 2 different solutions. One uses cursors and
> is incredibly fast, the other doesnt and is very slow.
>
> I created them as stored procedures so that i could stress test each more
> easily.
>
> The first solution, and nicest looking one is....
> ---------------------------------------------------------------------------
> Create procedure Tester2 (@Stockid as int)
> As
> Select tbl_Stocks.Price, tbl_Stocks.LastUpdate
> From tbl_Stocks
> Inner Join (
> Select Max(s.ID) AS Closest --, l.Code, s.LastUpdate
> From tbl_Stocks s
> Inner Join tbl_Times t
> On s.LastUpdate < (t.myDate + '2003-07-08')
> Where s.StockID=@StockID
> Group By t.myDate
> ) dt_Updates
> On dt_Updates.Closest = tbl_Stocks.ID
>
> The second, uglier one is...
> ---------------------------------------------------------------------------
> Create procedure Tester1 (@Stockid as int)
> As
>
> declare @myTime as smalldatetime
> declare @Result Table ( Price int, LastUpdate smalldatetime )
>
> Declare Time_Cursor cursor
> For
> Select myDate + '2003-07-08' From tbl_Times
>
> Open Time_Cursor
>
> Fetch Next From Time_Cursor Into @myTime
> While @@Fetch_Status = 0
> Begin
> Insert Into @Result
> Select Top 1 Price, LastUpdate
> From tbl_Stocks
> Where StockID=@StockID
> And LastUpdate < @myTime
> Order By LastUpdate Desc
>
> Fetch Next From Time_Cursor Into @myTime
> End
> Close Time_Cursor
> Deallocate Time_Cursor
> Select * From @Result
> ---------------------------------------------------------------------------
>
> And the results?
>
> I used a silly little bit of SQL to run each 100 times.
> Tester1 1 Second
> Tester2 148 Seconds
>
> Running Tester1 1000 Times however took 14 seconds, however i think most of
> this was spent in network congestion as the CPU's on the server didnt go
> over 30%. Tester2 however was using over 80%. So it seems that Tester1
> around 100 times faster (which is a pretty nice speed increase really!)...
> Also of note, my earlier incarnations of Tester2 (ie the single query
> approach) were taking over 20 seconds per SINGLE query.
>
> In this test case, tbl_Stocks has over 2 million records and tbl_Times has
> 9. The server is a Dual P4 2.4 Xeon, 1GB Ram. The data created from the
> queries is going to form the basis for charts.
>
> I hope this is of interest to some of you.
>
> Cheers!
>
> "Tommy" <blah@blah.com> wrote in message
> news:3f0c03a9$0$59955$c30e37c6@lon-reader.news.telstra.net...> join> > Hello, I am in a position where i need to create a query where i must> tbl_Time,> > two tables on the nearest value.
> >
> > Imagine i have 2 tables, tbl_Trade and tbl_Time. For each Time in> (which> > I need to locate the row in tbl_Trade where tbl_Time.LastUpdate is closest
> > to, but less than the value of tbl_Time.myTime.
> >
> > I have been using the followng query
> >
> > Select Avg(s.Price) AS Price , t.myTime
> > From tbl_Trade s
> > Inner Join tbl_Times t
> > On (t.myDate + '2003-07-08') > s.LastUpdate
> > AND (t.myDate + '2003-07-08' - '1:00 AM') < s.LastUpdate
> > Inner Join tbl_StockList l
> > On l.ID = s.StockID
> > Where l.Code = 'ORI'
> > Group By t.myTime
> >
> > But this relies on using an average of all trades in the time period> of> > in this case is 1 hour).
> >
> > Essentially the problem is that each trade can occur at any time, so there
> > is not necessarily a trade that occurs in that period, nor is an average> the> > the value of the average of the prices necessarily indicative of the value
> > we wish to retrieve.
> >
> > So basically what i want to be able to do is to generate a recordset of> using> > value of the price of the last trade at each hour O, O is specified in a
> > table. Is such a join possible? Or is there a work around aside from> > triggers to populate a table of prices for each hour for each commodity?
> >
> > Cheers
> >
> >Gert-Jan Strik Guest



Reply With Quote

