dbTalk Databases Forums  

Query improvement

comp.databases comp.databases


Discuss Query improvement in the comp.databases forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Libra
 
Posts: n/a

Default Query improvement - 02-09-2007 , 11:31 AM






Dear all,

I have a question about a query I would improve (I know it is not the best).

I have two tables:
USER:
Quote:
id | ...some data fields... |
DATA:
Quote:
id | users_id | ...some data fields... | timestamp |
I think they are quiet self explaining.

When a user update something, instead of update the related record, he
insert a new one (this is for keeping track of the changes).

Now, if I want to extract the _last record for each user_ I select all
the users firstly (there are no duplicates in USER table) and, then, for
each user I select the corresponding data records, sorted by descending
timestamping: the first of the returning set is the desired one.

So, if I have n users, I need n+1 queries. How to improve that (no
subqueries, I'm stuck with MySql 4)?

Thank you

Libra


Reply With Quote
  #2  
Old   
Ed Prochak
 
Posts: n/a

Default Re: Query improvement - 02-09-2007 , 01:56 PM






On Feb 9, 12:31 pm, Libra <libraramaANTIS... (AT) gmail (DOT) com> wrote:
Quote:
Dear all,

I have a question about a query I would improve (I know it is not the best).

I have two tables:
USER:
| id | ...some data fields... |

DATA:
| id | users_id | ...some data fields... | timestamp |

I think they are quiet self explaining.

When a user update something, instead of update the related record, he
insert a new one (this is for keeping track of the changes).

Now, if I want to extract the _last record for each user_ I select all
the users firstly (there are no duplicates in USER table) and, then, for
each user I select the corresponding data records, sorted by descending
timestamping: the first of the returning set is the desired one.

So, if I have n users, I need n+1 queries. How to improve that (no
subqueries, I'm stuck with MySql 4)?

Thank you

Libra

NO you do not need n+1 queries. (And I especially don't understand
where you got the +1)

First of all define what is the "last record" because a relational DB
has only rows , not records, and it stores sets of data, there is no
internal order to the rows.

I'll assume your id on the DATA table is a sequence that only
increases with each insert. So my definition is the row in DATA for a
given users_id (why you made that plural is puzzling) with the largest
id value. to get what you seem to want, you need a join and a group by
something like this:

select USER.id, max (DATA.id )
from USER, DATA
where USER.id=DATA.users_id
group by USER.id;

make that a view and you will be all set.

oh wait, no subqueries (or views??)
can you do it in multiple stages?
create table current_user_data (
user_id USER ID TYPE,
data_id DATA ID TYPE,
primary key (user_id, data_id) );

INSERT INTO current_user_data SELECT USER.id, max (DATA.id )
from USER, DATA
where USER.id=DATA.users_id
group by USER.id ;

now it's a threeway join of USER, DATA, and CURRENT_USER_DATA
you update CURRENT_USER_DATA on any insert into DATA.

(All untested, use at your own risk)

ed
(not a mySQL 4 user)



Reply With Quote
  #3  
Old   
Lew
 
Posts: n/a

Default Re: Query improvement - 02-09-2007 , 08:31 PM



Libra wrote:
Quote:
When a user update something, instead of update the related record, he
insert a new one (this is for keeping track of the changes).
I personally prefer putting history in a separate table rather than try to
sift through a bazillion time-separated copies in a transaction table.

I wonder what the best practice is. I do not know all ins and outs of the
arguments for the different approaches.

Quote:
(no subqueries, I'm stuck with MySql 4)
Given that MySQL is a free product, I am curious what the hindrance is to an
upgrade.

- Lew


Reply With Quote
  #4  
Old   
Libra
 
Posts: n/a

Default Re: Query improvement - 02-10-2007 , 06:44 AM



Lew ha scritto:
Quote:
(no subqueries, I'm stuck with MySql 4)

Given that MySQL is a free product, I am curious what the hindrance is
to an upgrade.
A really simple one: the server is not mine :-)
Libra



Reply With Quote
  #5  
Old   
--CELKO--
 
Posts: n/a

Default Re: Query improvement - 02-12-2007 , 10:26 AM



Here is a "cut & paste" on your question:

Think raw data and single facts when designing a table. Let me use a
history table for price changes. The fact to store is that a price
had a duration:

CREATE TABLE PriceHistory
(upc CHAR(13) NOT NULL
REFERENCES Inventory(upc),
start_date DATE NOT NULL,
end_date DATE, -- null means current
CHECK(start_date < end_date),
PRIMARY KEY (upc, start_date),
item_price DECIMAL (12,4) NOT NULL
CHECK (item_price > 0.0000),
etc.);

You actually needs more checks to assure that the start date is at
00:00 and the end dates is at 23:59:59.999 Hrs. You then use a
BETWEEN predicate to get the appropriate price.

SELECT ..
FROM PriceHistory AS H, Orders AS O
WHERE O.sales_date BETWEEN H.start_date
AND COALESCE (end_date, CURRENT_TIMESTAMP);

It is also a good idea to have a VIEW with the current data:

CREATE VIEW CurrentPrices (..)
AS
SELECT ..
FROM PriceHistory
WHERE end_date IS NULL;


Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.