Reputation: 826
currently my query looks like this:
SELECT alias.name killer,
SUM(kill_stats.amount) amount
FROM kill_stats
JOIN pickup ON pickup.logfile = 'CTFCL-20130813-1456-shutdown2'
JOIN account ON account.steam_id = '0:1:705272'
JOIN player victim ON victim.pickup_id = pickup.id AND victim.account_id = account.id
JOIN player killer ON killer.pickup_id = pickup.id AND kill_stats.killer_id = killer.id
JOIN alias ON killer.alias_id = alias.id
WHERE kill_stats.victim_id = victim.id AND NOT killer.team_id = victim.team_id
GROUP BY kill_stats.killer_id
ORDER BY amount DESC
kill_stats
table layout:
CREATE TABLE `kill_stats` (
`killer_id` int(11) UNSIGNED NOT NULL,
`victim_id` int(11) UNSIGNED NOT NULL,
`weapon_id` int(11) UNSIGNED NOT NULL,
`conced` bit(1) NOT NULL,
`fc` bit(1) NOT NULL,
`amount` int(11) UNSIGNED NOT NULL,
PRIMARY KEY(`killer_id`, `victim_id`, `weapon_id`, `conced`, `fc`),
CONSTRAINT `Ref_Killer` FOREIGN KEY (`killer_id`)
REFERENCES `player`(`id`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `Ref_Victim` FOREIGN KEY (`victim_id`)
REFERENCES `player`(`id`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `Ref_Weapon` FOREIGN KEY (`weapon_id`)
REFERENCES `weapon`(`id`)
ON DELETE CASCADE
ON UPDATE CASCADE
)
ENGINE=INNODB
CHARACTER SET utf8
COLLATE utf8_unicode_ci ;
Here a more readable view replacing the foreign keys with dummy data:
+-----------+-----------+-----------+--------+----+--------+
| killer_id | victim_id | weapon_id | conced | fc | amount |
+-----------+-----------+-----------+--------+----+--------+
| Josephine | Frank | RPG | NO | NO | 14 |
+-----------+-----------+-----------+--------+----+--------+
| Josephine | Frank | Shotgun | YES | NO | 5 |
+-----------+-----------+-----------+--------+----+--------+
| Josephine | Frank | Shotgun | NO | NO | 3 |
+-----------+-----------+-----------+--------+----+--------+
| Miguel | Frank | Knife | NO | NO | 1 |
+-----------+-----------+-----------+--------+----+--------+
Using this example table the query above would return a table like this:
+-----------+--------+
| killer | amount |
+-----------+--------+
| Josephine | 22 |
+-----------+--------+
| Miguel | 1 |
+-----------+--------+
What I would like the output to be is:
+-----------+-------------+--------------+-----------------+
| killer | total_kills | conced_kills | victim_had_flag |
+-----------+-------------+--------------+-----------------+
| Josephine | 22 | 5 | 0 |
+-----------+-------------+--------------+-----------------+
| Miguel | 1 | 0 | 0 |
+-----------+-------------+--------------+-----------------+
Showing how often a certain player was killed by other players, the total amount of times that they killed him, the amount of conced kills and how often the player carried the flag when he got killed by them.
I'm not really sure how to achieve that, I have tried GROUP BY kill_stats.killer_id, kill_stats.conced
but the result is:
+-----------+--------+
| killer | amount |
+-----------+--------+
| Josephine | 14 | -> the ones with kill_stats.conced = NO
+-----------+--------+
| Josephine | 5 | -> the ones with kill_stats.conced = YES
+-----------+--------+
| Miguel | 1 | -> the ones with kill_stats.conced = NO (only row for that `killer_id`)
+-----------+--------+
I get multiple rows for killer_id
and I want one row per killer_id
holding all the data.
Ike Walker's solution was almost what I have been looking for, the final query to make it work as I wanted is:
SELECT alias.name killer,
SUM(kill_stats.amount) as total_kills ,
SUM(CASE WHEN kill_stats.conced then kill_stats.amount ELSE 0 END) as conced_kills ,
SUM(CASE WHEN kill_stats.fc then kill_stats.amount ELSE 0 END) as victim_had_flag
FROM kill_stats
JOIN pickup ON pickup.logfile = 'CTFCL-20130813-1456-shutdown2'
JOIN account ON account.steam_id = '0:1:705272'
JOIN player victim ON victim.pickup_id = pickup.id AND victim.account_id = account.id
JOIN player killer ON killer.pickup_id = pickup.id AND kill_stats.killer_id = killer.id
JOIN alias ON killer.alias_id = alias.id
WHERE kill_stats.victim_id = victim.id AND NOT killer.team_id = victim.team_id
GROUP BY kill_stats.killer_id
ORDER BY amount DESC
The difference to his solution which finally put me on the right track is that I always needed to SUM()
kill_stats.amount into the new column conced_kills
for each row that has the BIT(1)
column set to 1.
Upvotes: 1
Views: 290
Reputation: 26333
Try changing your query's SELECT
list to this:
SELECT alias.name killer,
SUM(kill_stats.amount) amount,
SUM(kill_stats.conced) conced_kills,
SUM(kill_stats.fc) victim_had_flag
... and then pick up with the FROM kill_stats
and finish it exactly as you posted it. I'm assuming that conced
will be 1 if true and 0 if false; same with fc
. I'm also assuming that fc
indicates "victim had flag".
Upvotes: 0
Reputation: 65527
The standard way to do this is by combining SUM()
with CASE
for your secondary counts.
Here's your example query rewritten this way to give you the output you are looking for:
SELECT alias.name killer,
SUM(kill_stats.amount) as total_kills ,
SUM(CASE WHEN kill_stats.conced then 1 ELSE 0 END) as conced_kills ,
SUM(CASE WHEN kill_stats.fc then 1 ELSE 0 END) as victim_had_flag
FROM kill_stats
JOIN pickup ON pickup.logfile = 'CTFCL-20130813-1456-shutdown2'
JOIN account ON account.steam_id = '0:1:705272'
JOIN player victim ON victim.pickup_id = pickup.id AND victim.account_id = account.id
JOIN player killer ON killer.pickup_id = pickup.id AND kill_stats.killer_id = killer.id
JOIN alias ON killer.alias_id = alias.id
WHERE kill_stats.victim_id = victim.id AND NOT killer.team_id = victim.team_id
GROUP BY kill_stats.killer_id
ORDER BY amount DESC
Upvotes: 1