473,508 Members | 2,295 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Order By Join Column

103 New Member
I have a query in which I want to order the join table before joining it.

It's something like this:

Expand|Select|Wrap|Line Numbers
  1. SELECT product, price
  2. FROM prods
  3.   INNER JOIN subprods ON prodPk=prodFk ORDER BY price ASC
  4. GROUP BY prodPk
  5.  
Each product may have 1 or more subproducts with varying prices. I want to select a product and the lowest price from the list of sub-products.

Intuitively speaking, I would put the "order by" on the join. But clearly this doesn't work! I have also tried using a sub-query like this:

Expand|Select|Wrap|Line Numbers
  1. SELECT product, (SELECT price FROM subprods WHERE prodFk=prodPK ORDER BY price ASC LIMIT 0,1) AS price
  2. FROM prods
  3.  
This works but is taking about 8 seconds for the query to run (about 4000 rows returned). When I remove the sub-query, this drops to under 1 second.

Can anyone point me in the right direction?

Thanks

Henry
Jul 15 '08 #1
7 9427
coolsti
310 Contributor
Yes, you cannot do what you are trying to do using the order by before the group by. It won't work.

What you need to do is to use the query structure that I explain in my two posts on this thread:

You need something like the query technique that I explained in this thread:

http://bytes.com/forum/thread819577.html

See if that helps you, and post again if it isn't clear what to do.
Jul 16 '08 #2
coolsti
310 Contributor
Ok, I am completely bored at work at the moment, so I will try to make this query for you.

I do not have your tables in my database, so I do not know if the following is completely free of any syntax bugs, but this is basically what you need:

SELECT T1.product, T2.price from prods T1 inner join subprods T2 ON T1.prodPk=T2.prodFk inner join (SELECT T3.prodPk, MIN(T4.price) as minprice from prods T3 inner join subprods T4 ON T3.prodPk=T4.prodFk group by T3.prodPk) T5 where T1.prodPk = T5.prodPk and T2.price = T5.minprice.

Not all the table aliases are necessary, but at least doing it this way makes it clear which table's column is being used.

Basically you make a two part query. The subquery creates a table which I give the alias T5 which is composed just of what I assume is the unique index of the prods table `prodPk` and the minimum price for each. This table is your minimum price filter, and is used in a join with the first part of the query which selects the columns that you wish to see in your output.

In the subquery, you create as many columns as necessary in order to be able to distinctly select from the rows of the first part of the query. In this case, you need the prodPk index and of course the minium price to select.

The above solution has one flaw, however. If your subtable subprods has two entries for the same product with exactly the same price, and this price happens also to be the minium price, then your result will have two rows that are the same, for this product. If this could happen, you would then need to add a "DISTINCT", and I think if you place it after the first SELECT this will work.
Jul 16 '08 #3
henryrhenryr
103 New Member
Hi

Thanks for this solution - yes it does indeed work! The scenario with the same price for the subprod does exist and a group by right at the end solved that - select distinct didn't help.

I have to report, though, that i went for a work-around in the end as my main aim is shaving time off the query:

My initial solution (with simple sub-query) - about 22 seconds - ahh!
Your solution (with join and sub-query) - about 3.6 seconds
My work-around solution - about 1.5 seconds

My work-around involved making a new field called "cheapest" and running a 'slow' query to update that field with 1 for all the cheapest subprods. Then the query is a simple join with "cheapest=1" - easy. Then I put a little script which updates this every week which is about as much as it changes.

Thanks for your help! Actually I didn't know you could use sub-queries in place of tables until I read this so it has been very useful!

Henry
Jul 17 '08 #4
coolsti
310 Contributor
Henry, the idea to have another program running periodically to update your cheapest column is not a bad idea, but you are then dependent on this working and not stopping for some reason.

What you might consider: Try to perform the query I suggested, and add some extra column indexes here and there. In particular in things that are present in the where clauses. It is amazing how much faster a query can become by adding an index. I once speeded up a query from taking 10 seconds to taking about 0.1 second by adding one index.

If you can do this and find an index that can speed things up considerably, then you have all you need in the one query without the other program running periodically :)
Jul 17 '08 #5
coolsti
310 Contributor
Henry, the idea to have another program running periodically to update your cheapest column is not a bad idea, but you are then dependent on this working and not stopping for some reason.

What you might consider: Try to perform the query I suggested, and add some extra column indexes here and there. In particular in things that are present in the where clauses. It is amazing how much faster a query can become by adding an index. I once speeded up a query from taking 10 seconds to taking about 0.1 second by adding one index.

If you can do this and find an index that can speed things up considerably, then you have all you need in the one query without the other program running periodically :)
Afterthought: looking at your query, you may wish to try first to put an index on the product ID in the subprods table. If that does not speed things up, you could try instead to put an index on the price column. Both these columns are used in where clauses (for price, you need to find the minimum). Actually, for price, since you are looking for the minimum in a group by product ID, it may speed things up to make an index over both these columns together, that is one index defined on both columns.

However, try one thing at a time, and don't add more indexes than you need, as there is of course overhead (hardisk space and insert/update time) involved in having an index.

You could try to carry out your query but tack on the "EXPLAIN" keyword to the beginning of it. This then does not carry out your query, but gives you a table of information of how many rows need to be examined per table, and also may give you hints on where an index will help.

Regarding your "behind the scenes" program that updates the extra minimum price column, another thing you could consider doing is updating this information each time there is an update to the database. That is, you change whatever scripts are being used to update or insert rows into the database to also update the minimum price flag. This will work if the amount of effort to do this update is small compared to how often the database is updated. For example if the database is updated with many hits per second then this is probably not a good idea.
Jul 18 '08 #6
henryrhenryr
103 New Member
Hi

Thanks again for the useful pointers.

The tables were pretty much indexed up already - been caught there before ;). I still find it something of a mystery over which ones MySQL uses and I might try to test some 'combination' indexes to see if that works better...

The update script is working quite well. Actually the data are only updated once a week so it makes quite a lot of sense to use this. Good idea about updating when the data are changed though, I should be able to include that functionality quite easily...

Thanks for the thorough help!

Henry
Jul 24 '08 #7
coolsti
310 Contributor
Glad to help.

Try using the "EXPLAIN ....." syntax, where the keyword EXPLAIN is just added to the start of any query. If you do this, mysql will not carry out the query, but will give you a table showing what it needs to do to carry out the query. That is, it shows you how many rows in each table need to be searched, and what indexes are used.

This should then tell you what indexes are actually going to be used for a query, and which ones are not.

It also gives you some indication of where to add extra indexes. If you have several tables which indicate that ALL the rows need to be examined, then you should be able to speed up the query significantly by adding an appropriate index.
Jul 25 '08 #8

Sign in to post your reply or Sign up for a free account.

Similar topics

0
3547
by: VisionSet | last post by:
I have a query with 4 tables and plain 'JOIN's the explain gives the best join order, and it completes in 1.5 secs I add a single ORDER BY (a calculated column) and the join orders all shift and...
1
5735
by: melanie | last post by:
Hi, I open a recordset with a SQL query as its source. Then, i set the listbox.recordset = to the recordset i just opened. But, the fields appear in the listbox columns in a different order...
4
7540
by: dtwalter | last post by:
Is it possible to ORDER BY a SubSelect? I don't see why it wouldn't be, but I'm having some trouble. Hopefully it's just a simple error in syntax and somebody can tell me. Here's what I'm trying...
10
2174
by: OtisUsenet | last post by:
Hello, I am trying to select distinct dates and order them in the reverse chronological order. Although the column type is TIMESTAMP, in this case I want only YYYY, MM, and DD back. I am...
1
4641
by: Thomas Schoen | last post by:
Hi, is it possible to use a parameter of a plpgsql-function to order a selection inside the function? What i would like to do is pass a column-name/alias-name to a plpgsql function and use...
4
1952
by: VB Programmer | last post by:
I am trying to use a dropdownlist to fill in the ORDER BY of a SqlDataSource. Here's part of my HTML... <asp:SqlDataSource ID="VideoList" runat="server" ConnectionString="<%$...
2
1990
by: phillip.s.powell | last post by:
SELECT s.id, s.first_name, s.last_name, IF(s.school_year_id = 0, s.school_year_other, y.school_year_alt_display) AS school_year_name FROM student s LEFT OUTER JOIN school_year y ON...
29
27514
by: pb648174 | last post by:
I have the following basic statements being executed: Create a temp table, #TempPaging Insert Into #TempPaging (Col1, Col2) Select Col1, Col2 From SomeOtherTable Order By Col2, Col1 Select...
1
1013
by: weetat.yeo | last post by:
Hi all , I have 2 table as show below : When do join the 2 table using SQL statement , how i going to order by Table A sw_version then Table B card_sw_version_no column ? Anyone have ideas ?...
3
3850
by: ylekot88 | last post by:
Hi I am a student, I am trying to figure this out. I am trying to run a select statement that is asking for customer#, date, and total price of each order. ensure results are in chronological...
0
7225
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7326
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
7046
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
5627
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
4707
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3194
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3182
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
766
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
418
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.