GROUP BY и SELECT в SELECT

Моя проблема решена, но теперь у меня есть несколько вопросов производительности.

Мне нужен обзор моего пойманного покемонов для всех изданий, он работает, насколько я пытался, но я не думаю, что это лучшая практика.

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,00034sJOINs против Subquery 0,0030s/0,013sDuration / Fetch. Почему это так, время запуска в Joins быстрее, но длительность нет?

изображение дизайна db

И вот ссылка на sqlfiddle , с testdata.

mysql,sql,database-design,

1

Ответов: 2


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.


0

UPDATE: Иначе вы должны сделать что-то подобное для каждого издания.

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
MySQL, SQL, базы данных дизайн,
Похожие вопросы