Mysql column reordering numerically when a row deletes - mysql

I have a table like this
id Bill No Branches_id
1 1 1
2 2 1
3 3 1
4 1 2
5 4 1
when user deletes bill no 2 all other record's bill_no update in numerical order like this
id Bill No Branches_id
1 1 1
3 2 1
4 1 2
5 3 1
is there any easy way to reorder all records without a loop in programmatically

It appears that id is the primary key and you want to update another column within each bill. This can be reasonable.
You can use variables:
declare #rn := 0;
update likethis lt
set bill_no = (#rn := #rn + 1)
where lt.branches_id = 1
order by lt.id;
Note that all foreign references to the table should be using id. If bill_no is used to connect to another table, then you shouldn't change the value (even with cascading foreign keys), unless this is a very rare occurrence.

Related

How can I re-ordered the value of a column with some condition?

See the last two row where option_order is 0 but type is different. I want to keep them on first position for each type. How can I re-ordered the value of option_order column?
Here, the condition is, the '000' choice must be kept on first for each type by setting its position_order.
current table status:
MULTIPLE_CHOICE Table
id choice type option_order
1 AA 1 1
2 BB 1 2
3 CC 1 3
4 AAA 2 4
5 BBB 2 5
6 CCC 2 6
7 DDD 2 7
8 000 1 0
9 000 2 0
Required updated table:
This is what I need:
updated MULTIPLE_CHOICE Table
id choice type option_order
8 000 1 1
1 AA 1 2
2 BB 1 3
3 CC 1 4
9 000 2 5
4 AAA 2 6
5 BBB 2 7
6 CCC 2 8
9 DDD 2 9
The actual table is too big, so I cannot do this by edit. Please help for this complex query. I have no clue to solve this.
[Note: I need this to solve for mysql version 5.7]
Recalculate the whole column. Use, for example, user-defined variable:
UPDATE MULTIPLE_CHOICE
SET option_order = (#counter := #counter + 1)
WHERE (SELECT #counter := 0) = 0
ORDER BY type, choice;
fiddle
can you explain this condition: WHERE (SELECT #counter := 0) = 0. – HiddenHopes
This is a condition only formally - as you can see it is always TRUE. The aim of this construction is in variable initialization.
In SELECT queries we can initialise user-defined variables in separate subquery cross-joined to another tables, like:
SELECT {columnset}
FROM {tableset}
CROSS JOIN ( SELECT #variable := starting_value ) AS initialize_variables
{the rest clauses}
But we cannot do the same in UPDATE. The calculations are critically dependent by rows processing order, i.e. ORDER BY clause with the ordering expression which provides rows uniqueness is compulsory. But the subquery which initializes the variables will convert single-table UPDATE to multiple-table which does not support ORDER BY clause at all!
The way out of this situation is to initialize the variable in WHERE clause. When server builds query execution plan it evaluates all constant expressions, including ones in WHERE clause. Moreover, in UPDATE server MUST evaluate WHERE expression before updating because it must firstly determine the rows which will be updated, and only then update them. So the expression in WHERE will be evaluated before rows updating, and hence the variable will be initialized before rows iteration with guarantee.

Updating a table to increment a value per user id

I have the following table (called node_items):
id node_id position
== ======= ========
1 1 1
2 1 1
3 2 1
4 2 1
5 2 1
6 2 1
7 3 1
8 3 1
9 3 1
10 3 1
The position field is supposed to mark an items position in the node. They are currently all set at 1. I am wanting to fix this table by setting an incremental position for each item per node_id. So, the result I am after is:
id node_id position
== ======= ========
1 1 1
2 1 2
3 2 1
4 2 2
5 2 3
6 2 4
7 2 5
8 3 1
9 3 2
10 3 3
So I somehow need to group each item by node_id and set the position to an initial value of 1 and increment it for each subsequent item with that node_id.
Note: To keep my explanation simple, the above node_ids are shown in order (1,1, 2, 2,2,2,2,3,3,3), but this isn't usually the case.
What query can I use to update the position values incrementally for each node_id?
Fixing the table once can be done with an UPDATE:
SET #n = 0, #p = 1;
UPDATE node_items
SET position = (#p := IF(node_id=#n, #p+1, 1)),
node_id = (#n := node_id)
ORDER BY node_id, id;
Making the table maintain the position values as you insert/update/delete data is harder. Basically, can't do it while allowing concurrent updates. You have to lock the table in every session that needs to do writes to the table. This makes concurrent sessions run serially.
You can read my old post about this here: Some sort of “different auto-increment indexes” per a primary key values

How to update fields of one table using other table?

How can we update table 1 such that it will replace b field value of table 1 by that of table 2 where a field value are found same?
Suppose I have two tables
table 1
fields a b c
1 5 10
1 5 8
2 5 0
1 4 11
and
table 2
fields a b
1 6
1 7
2 5
1 4
I'm going on 6th form knowledge so I'll leave the code for you to do, but here's basically how I'd do it:Select all values from table 2For each value, select the rows from table 1 with the matching 'a' valueCount number of matching valuesIf it's over one, update table 1 set 'b' as the new value where 'a' matches
Edit: Oh, just realised, the 'a' values aren't unique, unless both tables have matching ID for each row, I'm not sure you can do it.

Autoincrement in mysql without unique ids

I have a table with main-ids and user-ids. Each user-id has a set of their own unique main-ids, but multiple user-ids can have the same main-id. Is there anyway to increment a main-id for a specific user without having to do 2 queries?
If you mean like this:
User ID Main ID
1 1
1 2
1 3
2 1
2 2
2 3
Then you're going to need to make an INSERT trigger that finds the next MainID for that user and stores that.

Updating a table in a Mysql database

Let's say I have in a table named threadloc:
id thread
4 1
3 2
2 3
1 4
for a table
I want to change the table value of thread so that I can pick any thread and put in on the bottom (id 1) and push all the other threads up one.
So like I pick 2 it would be:
id thread
4 1
3 3
2 4
1 2
UPDATE threadloc SET ID = ID + 1 WHERE thread <> #currentThread AND ID < #currentID;
UPDATE threadloc SET ID = 1 WHERE thread = #currentThread
edit: now it doesn't change higher IDs