Domanda

For those of you familiar with Minecraft, I am trying to count the number of blocks of each type broken by each user in a single SELECT query. I think that this is called a GROUP BY aggregate function. I think that I need to use multiple aggregate functions to accomplish my end-goal.

So far, I have only been able to:

  • Count the number of blocks of each type that have been broken
  • Count the total number of blocks broken by each user

I think that I need to use a GROUP BY function to COUNT the number of times that each block is broken, then GROUP by each user in a sub-query.


Problem pseudocode:

  • SELECT the player, block_id, count(*) WHERE the action_type is equal to "block-break"
  • COUNT the number times that a block has been broken (by counting the number of occurrences for each block_id)
  • GROUP BY the block_id

What I've tried: (output)

SELECT player, block_id, COUNT(block_id) FROM prism_actions WHERE action_type = 'block-break' GROUP BY block_id;

Also:([output])2

  • This function appears to compute the appropriate value.

SELECT player, block_id, count(*) as count from prism_actions where action_type = 'block-break' group by block_id,player order by block_id;


Table (prism_actions)

Field Type id int(11) unsigned action_time timestamp action_type varchar(20) player varchar(16) world varchar(255) x int(11) y smallint(5) z int(11) block_id mediumint(5) block_subid mediumint(5) old_block_id mediumint(5) old_block_subid mediumint(5) data varchar(255)


I have performed a similar GROUP BY aggregate query to count #(deaths|kills|blocks broken|blocks placed) per player

  • This query works as expected, but only requires a single GROUP BY function
  • Computes the SUM for each action based on the action_type (i.e. player-kill, player-death, block-break, block-place
  • Output is available below:

lower(player) kills deaths blocks_broken blocks_placed joey 41 4 4911 2678 kate 74 1 4944 4762 bill 129 4 2782 1271 jack 335 12 12403 5886

Code: SELECT LOWER(player), SUM(CASE WHEN action_type = 'player-kill' THEN 1 ELSE 0 END) AS kills, SUM(CASE WHEN action_type = 'player-death' THEN 1 ELSE 0 END) AS deaths, SUM(CASE WHEN action_type = 'block-break' THEN 1 ELSE 0 END) AS blocks_broken, SUM(CASE WHEN action_type = 'block-place' THEN 1 ELSE 0 END) AS blocks_placed FROM prism_actions WHERE action_type IN ('block-break', 'block-place', 'player-kill', 'player-death') AND LOWER(player) NOT IN ('creeper', 'fireball', 'environment') GROUP BY player;


Thank you in advance.

I realize that my rep is low on StackOverflow, but I hope that this does not influence your answer, or lead to any form of discrimination.

È stato utile?

Soluzione

Use the ROLLUP modifier here to get what you're after.

SELECT player, block_id, count(*) as count 
from prism_actions 
where action_type = 'block-break' 
group by player, block_id WITH ROLLUP
order by block_id;

This will give a record set similar to

Player | Block | Count
NULL     NULL    100
1        NULL    100
1        1       75
1        2       25

Where player =1 and block = NULL is the grand total, below that is the count by block type.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top