Well, I've found a solution after some more messing around. I've defined a
stored function that can do this for me. Here's the code for it:

CREATE
        FUNCTION loss_points (check_id BIGINT(20) UNSIGNED)
        RETURNS DOUBLE
        DETERMINISTIC
        READS SQL DATA
        BEGIN
                DECLARE done INT DEFAULT 0;
                DECLARE total DOUBLE DEFAULT 0.0;
                DECLARE loss DOUBLE;
                DECLARE loss_cursor CURSOR FOR SELECT 
IFNULL(SUM(items.basePrice *
lost.quantity * IF(items.techLevel > 1, 10, 1)), 0)+(ships.basePrice *
IF(ships.techLevel > 1, 10, 1)) AS totalValue FROM kb__killmails AS
mails LEFT JOIN kb__items_lost AS lost ON (lost.mail_id=mails.id) LEFT
JOIN kb__items AS items ON (lost.item_id=items.typeID) INNER JOIN
kb__items AS ships ON (mails.ship_id=ships.typeID) WHERE
mails.player_id=check_id GROUP BY mails.id;
                DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

                OPEN loss_cursor;

                REPEAT
                        FETCH loss_cursor INTO loss;
                        IF loss IS NOT NULL THEN
                                SET total = total+loss;
                        END IF;
                UNTIL done END REPEAT;

                CLOSE loss_cursor;

                RETURN total;
        END

(not bothering to simplify table names this time)

I would of had this sooner, but I hadn't set the default value for
'total', and so it was always returning null, because any math involving a
null value returns null. :)

If anyone has a better solution, or some reccomendations, I'll be glad to
hear them.

On Mon, September 25, 2006 2:04 pm, Matthew Walker wrote:
> I'm trying to do a rather tricky query in MySQL, and I'm a bit stumped. I
> know I can do what I want if I just offload the work to PHP, but for the
> sake of the learning, I'm trying to do it inside SQL.
>
> A bit of background: This is a 'point tracking' site for PVP in EVE
> Online. It parses kill reports, and stores them in the database. Now I'm
> trying to get it to tally up points per kill, based on the value of the
> items destroyed.
>
> Relevant Schema:
>
> CREATE TABLE `items` (
>   `id` int(11) NOT NULL auto_increment,
>   `typeName` char(100) default NULL,
>   `graphicID` int(11) default NULL,
>   `basePrice` double default NULL,
>   `techLevel` tinyint(3) unsigned NOT NULL,
>   PRIMARY KEY  (`id`),
>   UNIQUE KEY `typeName` (`typeName`),
>   KEY `graphicID` (`graphicID`)
> ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
>
> -- --------------------------------------------------------
>
> CREATE TABLE `lost` (
>   `mail_id` bigint(20) unsigned NOT NULL,
>   `item_id` bigint(20) unsigned NOT NULL,
>   `quantity` bigint(20) unsigned NOT NULL,
>   `location` enum('cargo','fit','drone_bay') NOT NULL
> ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
>
> -- --------------------------------------------------------
>
> CREATE TABLE `mails` (
>   `id` bigint(20) unsigned NOT NULL auto_increment,
>   `player_id` bigint(20) unsigned NOT NULL,
>   `corporation_id` bigint(20) unsigned NOT NULL,
>   `alliance_id` bigint(20) unsigned NOT NULL,
>   `ship_id` bigint(20) unsigned NOT NULL,
>   `system_id` bigint(20) unsigned NOT NULL,
>   `timestamp` datetime NOT NULL,
>   `hash` varchar(32) NOT NULL,
>   `mail` longtext NOT NULL,
>   PRIMARY KEY  (`id`)
> ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
>
> I've got a query that does most of the work of generating the cost of all
> of a person's losses:
>
> SELECT IFNULL(SUM(items.basePrice * lost.quantity * IF(items.techLevel >
> 1, 10, 1)), 0)+(ships.basePrice * IF(ships.techLevel > 1, 10, 1)) AS
> totalValue 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
>
> However, this returns 1 row per kill, and I would like to get it to return
> simply one value, that is a total of all the losses. Simple to do in PHP
> with what I have, but I can't find a way to do it directly in the SQL.
>
> I've tried SUM()'ing a subselect, but that returns null, so I guess I
> don't understand subselects. :)
>
> Oh, and flame my language/DB choice all you want. I know them, and they're
> good enough for me. If there isn't a way to do this in-db, I'll survive
> with doing it in the PHP.
>
> Thanks.
> --
> Matthew Walker
> Kydance Hosting & Consulting
> LAMP Specialist
>
> /*
> PLUG: http://plug.org, #utah on irc.freenode.net
> Unsubscribe: http://plug.org/mailman/options/plug
> Don't fear the penguin.
> */
>


-- 
Matthew Walker
Kydance Hosting & Consulting
LAMP Specialist

/*
PLUG: http://plug.org, #utah on irc.freenode.net
Unsubscribe: http://plug.org/mailman/options/plug
Don't fear the penguin.
*/

Reply via email to