Как создать последовательность выбранных значений в MySQL?

Я пытаюсь создать запрос, который выберет команду из объявленной переменной, а затем сделает оставшиеся команды «анонимными», предоставив им общие бренды и последовательные идентификаторы.

Например, если в моем наборе данных есть 3 разных названия команд (ABC, DEF и GHI), но я бы хотел, чтобы отображалось только истинное значение 1 выбранной команды (ABC). Вот скелет запроса, с которым я работаю:

SET @teamid = 123;

SELECT     CASE WHEN ID = @teamid
                THEN NAME
                ELSE 'Team' + ' - ' + SEQ
                END AS 'Team Name',
           SUM(TOTAL) AS 'Team Total'
FROM       TEAM
GROUP BY   1;

Я хотел бы, чтобы результаты выглядели примерно так:

 Team Name:    Team Total:
 ABC           100
 Team - 1      50
 Team - 2      150

Как я могу создать запрос, который создаст уникальный номер, которым я могу заменить исходное название команды? Я знаю, что мне нужно заменить часть «SEQ» оператора case, но я не уверен, чем именно ее заменить. Кроме того, важно, чтобы каждая команда имела один и тот же идентификатор, независимо от того, анонимна она или нет (поэтому, если команда DEF имеет 50 строк, она должна отображаться только как «Команда — 1», а не как «Команда — 1-50»), чтобы мои группировки работать должным образом.

Спасибо за помощь.


person dupton    schedule 19.05.2015    source источник
comment
@MattBusche Это для SQL-сервера, а не для MySQL.   -  person Barmar    schedule 20.05.2015
comment
ROWNUM()... интересно, не думал об этом. Это помогло бы с точки зрения получения уникального идентификатора, но я больше надеялся на средство, которое обеспечило бы более рациональный подход. Я, вероятно, могу создать временную таблицу и присоединиться к таблице Team и в основном изменить оператор CASE, который у меня был выше, чтобы использовать ROWNUM(), но в любом случае можно исключить этот шаг с помощью процедуры последовательного типа. В любом случае, оцените ответ.   -  person dupton    schedule 20.05.2015
comment
@dupton MySQL не имеет ROWNUM. Этот ответ для SQL-сервера, а не для MySQL.   -  person Barmar    schedule 20.05.2015


Ответы (2)


Используйте определяемую пользователем переменную, которую вы увеличиваете. Кроме того, MySQL использует CONCAT для объединения строк, а не +.

SET @teamid = 123;

SELECT     CASE WHEN ID = @teamid
                THEN NAME
                ELSE CONCAT('Team  - ', @SEQ)
                END AS 'Team Name',
           SUM(TOTAL) AS 'Team Total',
           @SEQ := CASE WHEN ID = @teamid 
                        THEN @SEQ
                        ELSE @SEQ + 1
                   END
FROM       TEAM
CROSS JOIN (SELECT @SEQ := 1) AS vars
GROUP BY   ID;

ДЕМО

person Barmar    schedule 19.05.2015
comment
Спасибо Бармар. Также отметил ваш комментарий о ROWNUM(). Ваша демонстрация выглядит великолепно (никогда не видел этот сайт раньше, действительно круто), но когда я пробую его на своем экземпляре MySQL, я возвращаю BLOB-объекты как для столбца Team Names, так и для столбца SEQ (я удалил Team Totals, чтобы избавиться от некоторых беспорядок). Любая идея, почему это может происходить? - person dupton; 20.05.2015
comment
Столбец @SEQ можно игнорировать, он нужен внутри запроса. Я не уверен, почему вы получаете капли для названия команды. Каков тип данных NAME? - person Barmar; 20.05.2015
comment
Тип данных имени — varchar(50). Как мне скрыть/игнорировать часть SEQ сразу после Team Total, если я не хочу, чтобы она была включена в данные? Извините, если это глупый вопрос, это довольно новое для меня. - person dupton; 20.05.2015
comment
Вы можете поместить это в подзапрос, и тогда внешний запрос сможет выбрать только столбцы Team Total и Team Name. - person Barmar; 20.05.2015
comment
Выше упоминалось, что приведение @SEQ устранило проблему с BLOB, то же самое с этим запросом. Спасибо Бармар. - person dupton; 20.05.2015
comment
Мне никогда не приходилось делать это при объединении строк с целыми числами в MySQL, он всегда обрабатывает это автоматически. Интересно, зачем вам это нужно. - person Barmar; 20.05.2015

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

SET @teamid := [the id you want];
SET @prevName := "";
SET @team_i := 0;

SELECT `Team Name`, SUM(TOTAL) AS `Team Total`
FROM (
   SELECT @team_i := @team_i + IF(@prevName <>NAME, 1, 0) AS `teamIndex`
      , @prevName := NAME AS `OriginalName`
      , IF(ID = @teamid, NAME, CONCAT('Team  - ', @team_i)) AS `Team Name`
      , TOTAL
   FROM TEAM
   ORDER BY NAME) AS subQ
GROUP BY `Team Name`;

и на самом деле его можно вероятно обратить (и этот может быть немного быстрее, хотя в конечном итоге вы получите дополнительные поля в окончательных результатах):

SET @teamid := [the id you want];
SET @prevName := "";
SET @team_i := 0;

SELECT @team_i := @team_i + IF(@prevName <>NAME, 1, 0) AS `teamIndex`
      , @prevName := NAME AS `OriginalName`
      , IF(ID = @teamid, NAME, CONCAT('Team  - ', @team_i)) AS `Team Name`
      , `Team Total`
FROM (
   SELECT `NAME`, SUM(TOTAL) AS `Team Total`
   FROM TEAM
   GROUP BY NAME) AS subQ
ORDER BY `NAME`;
person Uueerdo    schedule 19.05.2015
comment
Это тоже выглядит как хороший подход, но я столкнулся с той же проблемой, что и с предложением Бамара, когда вывод отображается как BLOB. Любые мысли о том, почему это произойдет? Тип данных Team Name - это varchar (50), и я пытался преобразовать его в char, но не в кости. - person dupton; 20.05.2015
comment
Итак, похоже, я смог исправить проблему с BLOB, приведя переменные к CHAR (50), и это работает отлично. Спасибо амиго! - person dupton; 20.05.2015