Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

151
Visualizações
Increment value depending other one

Let's assume I have the table:

id | val_1 | val_2
1  |  1    |  0
2  |  1    |  1 
3  |  1    |  2
4  |  2    |  0

val_2 should be zero at first if there was no rows with val_1 before. Otherwise it should be previous val_2 + 1 for this val_1.

I can't figure it out by myself the best way to do it. The one thing I've invented is trigger after insert, but I think here maybe some other way to do it cleaner and faster? My code is something like:

DELIMITER $$

CREATE TRIGGER after_table_insert
AFTER INSERT
ON table FOR EACH ROW
BEGIN
    UPDATE table SET val_2 = t.val_2 + 1 
    FROM (
        SELECT val_2 FROM table WHERE val_1 = new.val_1 ORDER BY id DESC LIMIT 1
    ) t
    WHERE id = new.id;
END$$

DELIMITER ;

I will appreciate for any help! Have a great day/night.

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

You have couple of issues with such setup:

  1. What's going on if you UPDATE or DELETE rows? It can mess up everything with val2. Be careful with that.

  2. Val2 can always be calculated and there is no need to store it.

Having said that, below I will show you a setup with which I will store only id and val1. Then val2 will be calculated within the SELECT statement (so it will always be correct).

CREATE TABLE vals(
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    val INT NOT NULL
);

INSERT INTO vals(val) VALUES(1),(1),(1),(2);

Now what I am going to do is to use the ROW_NUMBER() function (which prints the row number) and run it over a PARTITION BY val:

SELECT  id, val,
        ROW_NUMBER() OVER (
            PARTITION BY val
        ) AS val2
FROM vals;

We are almost there. Sadly it will offset them by 1 compared to what you need:

+----+-----+------+
| id | val | val2 |
+----+-----+------+
|  1 |   1 |    1 |
|  2 |   1 |    2 |
|  3 |   1 |    3 |
|  4 |   2 |    1 |
+----+-----+------+

The fix is simple. Just add "-1" to it and you are ready.

SELECT  id, val,
        -1+ROW_NUMBER() OVER (
            PARTITION BY val
        ) AS val2
FROM vals;

This will produce:

+----+-----+------+
| id | val | val2 |
+----+-----+------+
|  1 |   1 |    0 |
|  2 |   1 |    1 |
|  3 |   1 |    2 |
|  4 |   2 |    0 |
+----+-----+------+

With this solution there is no need to store val2 at all (you can create it as a VIEW if you wish) and it is not vulnerable to the issue when you delete a row (it will continue to work properly).

over 4 years ago · Santiago Trujillo Relatório

0

This is one possibility

Schema (MySQL v5.7)

CREATE TABLE table1 (
  `id` INTEGER,
  `val_1` INTEGER,
  `val_2` INTEGER
);

DELIMITER //

CREATE TRIGGER after_table_insert
BEFORE INSERT
ON table1 FOR EACH ROW
BEGIN
    SET @maxval2 = 0;
    SELECT max(val_2) + 1 into @maxval2 FROM table1 WHERE val_1 = new.val_1;
    IF @maxval2 IS NULL THEN
        SET @maxval2 = 0;
    END IF;
    SET NEW.val_2 = @maxval2; 
END//

DELIMITER ;

INSERT INTO table1
  (`id`, `val_1`, `val_2`)
VALUES
  ('1', '1', '0'),
  ('2', '1', '0'),
  ('3', '1', '0'),
  ('4', '2', '0'),
  ('4', '2', '0');

Query #1

SELECT * FROM table1;

| id  | val_1 | val_2 |
| --- | ----- | ----- |
| 1   | 1     | 0     |
| 2   | 1     | 1     |
| 3   | 1     | 2     |
| 4   | 2     | 0     |
| 4   | 2     | 1     |

View on DB Fiddle

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda