Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

147
Views
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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!