Mysql
 sql >> база данни >  >> RDS >> Mysql

Как може подгрупите да имат добавена генерирана колона с нарастване в sql заявка?

Реших го, благодарение на помощта от най-отлична публикация в блога тук:http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/

Решението е нетривиално, изисква променливи и някои напреднали познания за това как mysql подрежда своите заявки, но изглежда е доста производително. Един от ключовете е, че присвояването на променливи могат да бъдат скрити в извикванията на функции!

По същество следната заявка решава проблема:

SET @num := 0, @type := '';

SELECT name, subgroup, @num AS increment
FROM table_name
WHERE 0 <= GREATEST(
   @num := IF(@type = subgroup, @num + 1, 1),
   LEAST(0, LENGTH(@type := subgroup)))

Функциите GREATEST , LEAST и LENGTH са там само като контейнери за присвояване на променливи. Както можете да видите, тези функции по същество не правят нищо, за да повлияят на изхода на заявката.

Но също така открих, че имам стойности на „подгрупа“ в таблицата си, които не са последователни. Например:

+------+----------+
| name | subgroup |
+------+----------+
| john | 1        |
| doe  | 1        |
| jim  | 1        |
| greg | 2        |
| boe  | 2        |
| amos | 3        |
| ben  | 1        |
| gary | 2        |
+------+----------+

Резултатът е изходна таблица, както следва:

+------+----------+-----------+
| name | subgroup | increment |
+------+----------+-----------+
| john | 1        |         1 |
| doe  | 1        |         2 |
| jim  | 1        |         3 |
| greg | 2        |         1 |
| boe  | 2        |         2 |
| amos | 3        |         1 |
| ben  | 1        |         1 |
| gary | 2        |         1 |
+------+----------+-----------+

Прокарване на ORDER BY клаузата в края на заявката не работи поради реда за изпълнение и скриването на присвояването на променливи в ORDER BY клаузата се доближи, но имаше свои собствени проблеми, така че ето последната заявка, която използвах:

SET @num := 0, @type := '';

SELECT name, subgroup, @num AS increment
FROM (SELECT * FROM table_name ORDER BY subgroup) AS table_name2
WHERE 0 <= GREATEST(
   @num := IF(@type = subgroup, @num + 1, 1),
   LEAST(0, LENGTH(@type := subgroup)))

Резултатът е следния изход:

+------+----------+-----------+
| name | subgroup | increment |
+------+----------+-----------+
| john | 1        |         1 |
| doe  | 1        |         2 |
| jim  | 1        |         3 |
| ben  | 1        |         4 |
| greg | 2        |         1 |
| boe  | 2        |         2 |
| gary | 2        |         3 |
| amos | 3        |         1 |
+------+----------+-----------+

Ура!



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Преразпределете гласовете, като елиминирате кандидатите

  2. Коригирайте синтактична грешка на mysql при създаване на потребител

  3. Как да изтрия определен ред от таблицата на mysql със същите стойности на колоните?

  4. MySQL:как да индексираме клауза ИЛИ

  5. Има ли спад в производителността, ако има твърде много колони в таблица?