MySQL query id generation - mysql

I have table and when I add a new row I want to calculat an id number to it.
conditions:
if i have missing number give the smallest one (3)
if i have no missing number than give the next number that comes in a row (5)
How can I build this conditions into my query?
My query:
INSERT INTO sample(product) VALUES ('$product')
table
product
id
name1
1
name2
2
name4
4
solution if I have missing id
product
id
name1
1
name2
2
name4
4
name5
3
solution if I have no missing id
product
id
name1
1
name2
2
name3
3
name4
4
name5
5

MySQL has a feature to generate an auto-increment id. See https://dev.mysql.com/doc/refman/8.0/en/example-auto-increment.html
The number is always incremented. It does not go back and fill in missing id values. This is deliberate and necessary to prevent race conditions while concurrent sessions are inserting rows.
If you want to find unused values as you insert a new row, you find that to prevent two concurrent sessions from using the same value, you end up having to lock the whole table. This hurts performance for many apps.
You should drop the requirement that the id values must be consecutive. They are not ordinal row numbers. You may always have missing id values, because you may delete rows, or rollback a transaction that inserts a row, or the auto-increment mechanism can even skip values as it generates them.

Related

"Merging" ids together in SQL

I have a table cities like this:
id
city
1
Vancouver
2
Calgary
3
Calgry
And multiple other tables which reference cities, something like this (just some example numbers).
id
city_id
year
population
1
1
2000
100000
2
1
2001
130000
3
3
2000
70000
4
3
2001
85000
5
2
2002
95000
I want to merge/consolidate city id 3 into id 2, so change every occurrence of id 3 across all tables to 2, and then delete city id 3. Is there a clean way of doing this?
Something like ON UPDATE CASCADE would work perfectly but I can't have duplicate primary ids. At the very least I could loop through the foreign keys and run a query on every table but I'm not sure if there's a more idiomatic way.
ON UPDATE CASCADE causes duplicate PK. To avoid that, we can use ON DELETE SET NULL which nullify all the city_id with a value 3 in other tables once we delete the city_id 3 from the cities table, but then you would still have to change the city_id from null to 2 in the said tables. This is not fundamentally different to change those city_id with a value 3 to 2 for the other tables , then just delete id 3 from the cities table. If you feel reluctant to manually do that or if there are too many tables to handle, then use a procedure. Make a list of table , declare a cursor for the list and loop through the list to get each table name and use a prepared statement to do the UPDATE.

MySQL Fastest Way To Handle Composite Key Query

I'm having some issues with slow queries on a MySQL database with many rows and I'm just hoping to make sure I'm doing this right.
I have a table that contains a TAID with an associated Row like this:
Row | TAID
----------
1 1
2 1
3 1
4 1
1 2
2 2
3 2
4 2
Currently I have TAID, Row setup as a Composite Key, but I generally query all the rows using the TAID column.
Is it slow because there are multiple instances of the TAID?
Am I thinking about this the right way?
Edit: I think the order of the columns is the problem.
I actually have the Row before the TAID and I'm querying on the TAID.
Going to try flipping the order.
As suggested the order of the Composite keys needed to be flipped.
Since I'm querying on the TAID, it needs to be the first key.

T-SQL query procedure-insert

I am wondering if any of you would be able to help me. I am trying to loop through table 1 (which has duplicate values of the plant codes) and based on the unique plant codes, create a new record for the two other tables. For each unique Plant code I want to create a new row in the other two tables and regarding the non unique PtypeID I link any one of the PTypeID's for all inserts it doesnt matter which I choose and for the rest of the fields like name etc. I would like to set those myself, I am just stuck on the logic of how to insert based on looping through a certain table and adding to another. So here is the data:
Table 1
PlantCode PlantID PTypeID
MEX 1 10
USA 2 11
USA 2 12
AUS 3 13
CHL 4 14
Table 2
PTypeID PtypeName PRID
123 Supplier 1
23 General 2
45 Customer 3
90 Broker 4
90 Broker 5
Table 3
PCreatedDate PRID PRName
2005-03-21 14:44:27.157 1 Classification
2005-03-29 00:00:00.000 2 Follow Up
2005-04-13 09:27:17.720 3 Step 1
2005-04-13 10:31:37.680 4 Step 2
2005-04-13 10:32:17.663 5 General Process
Any help at all would be greatly appreciated
I'm unclear on what relationship there is between Table 1 and either of the other two, so this is going to be a bit general.
First, there are two options and both require a select statement to get the unique values of PlantCode out of table1, along with one of the PTypeId's associated with it, so let's do that:
select PlantCode, min(PTypeId)
from table1
group by PlantCode;
This gets the lowest valued PTypeId associated with the PlantCode. You could use max(PTypeId) instead which gets the highest value if you wanted: for 'USA' min will give you 11 and max will give you 12.
Having selected that data you can either write some code (C#, C++, java, whatever) to read through the results row by row and insert new data into table2 and table3. I'm not going to show that, but I'll show how the do it using pure SQL.
insert into table2 (PTypeId, PTypeName, PRID)
select PTypeId, 'YourChoiceOfName', 24 -- set PRID to 24 for all
from
(
select PlantCode, min(PTypeId) as PTypeId
from table1
group by PlantCode
) x;
and follow that with a similar insert.... select... for table3.
Hope that helps.

MySQL, Select, Merge tables

I have a little problem that I can´t solve. It´s really simple, but I just can´t figure it out and have search some time but not found any good answers.
I have two tables:
Transaction
t_nr (Primary) a_nr quantity
1 1 10
2 2 10
Customer
c_nr (PRIMARY) name city
1 Mario Tokyo
2 Luigi Beijing
And want to insert values from the two above into another table with one query looking
Account
a_nr (primary) c_nr
Problem is that when just making a regular select-from-statement it returns:
a_nr c_nr
1 1
1 2
2 1
2 2
i.e. not just merges them together in the account table.
a_nr c_nr
1 1
2 2
How do I do this?
Does a_nr correlate to c_nr (are they equal)?
If so,
insert into account (a_nr,c_nr)
SELECT transaction.a_nr, customer.c_nr from transaction, customer
WHERE transaction.a_nr = customer.c_nr
Although this seems completely pointless to only insert two values that are the same.
What is the desired output of Account?

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.