MySQL Query Guidance Needed
Matthew Walker
rorith at kydance.net
Mon Sep 25 15:57:22 MDT 2006
On Mon, September 25, 2006 3:48 pm, Nicholas Leippe wrote:
> On Monday 25 September 2006 14:58, Matthew Walker wrote:
>> On Mon, September 25, 2006 2:47 pm, Hill, Greg wrote:
>> > Maybe I'm misunderstanding something in your query, but it seems you
>> > could just drop the GROUP BY to get a total sum, or GROUP BY player_id
>> > to get sum per player (and drop the where clause).
>
> If you do this then you are multiplying the value of each ship by the
> number
> of items in the ship. The result you desire requires the sum of data with
> two different group criteria, thus it must be split up.
Really? Because my tests don't bear that out. Odd. I thought of that too,
and made sure to sanity-check the totals I was getting.
>
> Pushing the entire query as-is into a subquery does the same thing as
> dropping
> the GROUP BY.
>
> You need to separate it into the sum of two results:
>
> SELECT
> (SELECT # item total
> IFNULL(SUM(items.basePrice * lost.quantity * IF(items.techLevel > 1,
> 10, 1)), 0) AS items_total
> FROM mails
> LEFT JOIN lost ON (lost.mail_id = mails.id)
> LEFT JOIN items ON (lost.item_id = items.id)
> WHERE mails.player_id = 6
> ) +
> (SELECT # item total
> SUM(ships.basePrice * IF(ships.techLevel > 1,
> 10, 1)) AS ships_total
> FROM mails
> LEFT JOIN lost ON (lost.mail_id = mails.id)
> LEFT JOIN items AS ships ON (lost.item_id = ships.id)
> WHERE mails.player_id = 6
> )
>
> This can be done in more than one way, here's a method with a subselect,
> derived from your original query:
>
> SELECT SUM(items_value) + SUM(ship_value)
> FROM (
> SELECT
> IFNULL(SUM(items.basePrice * lost.quantity * IF(items.techLevel > 1,
> 10, 1)), 0) AS items_value,
> ships.basePrice * IF(ships.techLevel > 1,
> 10, 1) AS ship_value
>
> FROM mails
> LEFT JOIN lost ON (lost.mail_id = mails.id)
> LEFT JOIN items ON (lost.item_id = items.id)
> INNER JOIN items AS ships ON (mails.ship_id = ships.id)
> WHERE mails.player_id = 6
> GROUP BY mails.id
> ) a
>
> You may want to EXPLAIN a few variations and play with indexes to find the
> one
> with the best performance.
Excellent reccomendations, and I'll definately have to take a look at the
performance. This is the trickiest querying I've done in a while, and it's
fun. I love a challenge. Note that despite 'solving' the problem with a
stored function, I'm still not satisfied. :)
--
Matthew Walker
Kydance Hosting & Consulting
LAMP Specialist
More information about the PLUG
mailing list