SELECT中的GROUP BY和SELECT

时间:2016-10-15 19:08:19

标签: mysql sql database-design

我的问题已经解决,但现在我遇到了一些性能问题。

我想要了解所有版本的被捕捉的口袋妖怪的概述,它尽我所能,但我不认为这是最好的做法。

select 
  #p.idpokemons as ID,
  #p.name as Pokemon,
  #t.name as Trainer,
  tpe.idpokemons as ID,
  (select name from pokemons p where p.idpokemons = tpe.idpokemons) as Pokemon,
  (select name from trainer t where t.idtrainer = tpe.idtrainer) as Trainer,
  max(case when ideditions = 'x' then status end) as statusX, 
  max(case when ideditions = 'y' then status end) as statusY, 
  max(case when ideditions = 'or' then status end) as statusOR, 
  max(case when ideditions = 'as' then status end) as statusAS, 
  max(case when ideditions = 'sun' then status end) as statusSun, 
  max(case when ideditions = 'moon' then status end) as statusMoon 
from trainer_pokemon_edition tpe
#JOIN pokemons p ON p.idpokemons = tpe.idpokemons
#JOIN trainer t ON t.idtrainer = tpe.idtrainer
group by tpe.idpokemons;

修改 刚刚将查询更改为类似于Thorstens的回答,因为它比旧版更快。 我对连接进行了评论,因为在我的应用程序中,我返回721行并且使用连接,查询比使用子查询0,021s/0,00034s JOIN慢于0,0030s/0,013s子查询持续时间/提取。 为什么会这样,加入的获取时间更快,但持续时间不是?

image of db design

以下是sqlfiddle与testdata的链接。

2 个答案:

答案 0 :(得分:0)

更新: 否则你必须为每个版本做这样的事情。

SELECT 
  p.name AS Pokemon,
  t.name AS Trainer,
   case when max(redCaught.idpokemons) is not null then 'Caught' else 'No' end as 'Red',
   case when max(blueCaught.idpokemons) is not null then 'Caught' else 'No' end as 'Blue'
FROM
  trainer_pokemon_edition tpe
  left join (select distinct idpokemons,idtrainer from trainer_pokemon_edition tpe where status = "Caught" and ideditions='r') redCaught 
  on redCaught.idpokemons = tpe.idpokemons and tpe.ideditions='r' and redCaught.idtrainer = tpe.idtrainer
   left join (select distinct idtrainer,idpokemons from trainer_pokemon_edition tpe where status = "Caught" and ideditions='b') blueCaught 
  on blueCaught.idpokemons = tpe.idpokemons and tpe.ideditions='b' and blueCaught.idtrainer = tpe.idtrainer
   inner JOIN pokemons p ON p.idpokemons = tpe.idpokemons
   inner JOIN trainer t ON t.idtrainer = tpe.idtrainer
  group by tpe.idpokemons,tpe.idtrainer;

做这样的事情会不会更容易?

SELECT distinct
  p.idpokemons AS ID,
  p.name AS Pokemon,
  t.name AS Trainer,
  e.name,
  tpe.status
FROM
  trainer_pokemon_edition tpe
  JOIN pokemons p ON p.idpokemons = tpe.idpokemons
  JOIN trainer t ON t.idtrainer = tpe.idtrainer
  join editions e on e.ideditions = tpe.ideditions
 where status = "Caught"
GROUP BY
  Pokemon,tpe.idtrainer,status

答案 1 :(得分:0)

你想要展示你所有的小宠物及其状态吗?但是每个口袋妖怪都有很多trainer_pokemon_edition记录,因此每个x,每y等可以有不同的状态。你必须决定要显示哪个;最大值?显示所有状态的串联字符串?别的什么?同样奇怪的是,有一个表格包含版本,但您的查询处理某些版本并将其显示在列中。

然而,要获得每个口袋妖怪的状态,只需汇总您的数据:

select 
  (select name from pokemons p where p.idpokemons = tpe.idpokemons) as pokemon,
  max(case when ideditions = 'x' then status end) as statusx, 
  max(case when ideditions = 'y' then status end) as statusy, 
  max(case when ideditions = 'or' then status end) as statusor, 
  max(case when ideditions = 'as' then status end) as statusas, 
  max(case when ideditions = 'sun' then status end) as statussun, 
  max(case when ideditions = 'moon' then status end) as statusmoon, 
  max(case when ideditions = 'b' then status end) as statusb, 
  max(case when ideditions = 'r' then status end) as statusr 
from trainer_pokemon_edition tpe
group by idpokemons;

当然,你也可以加入pokemons表,而不是在select子句中的子查询中获取名称。