I have a database with many entries, starting with ID 100000 and ending at ID 200000.
Now I'm trying to set the first and lowest ID to 1, and decrease on each next ID +1
So the new first ID would be 1, and the last and highest would be 99000 in that example.
Is there any mysql query, which updates the rows from a given number, and +1 for each next row?
You can use a row number query in update and join with same table but update id with row number result from joined result set
update t
join (
select id,#r:=#r+1 `row`
from t
cross join (select #r:=0) t1
) t2 on (t.id = t2.id)
set t.id = t2.row
Note: donot directly run this query on your production database first test it with a copy of your database if result is successful
then apply on production database
Fiddle Demo
Related
I have two tables that are very similar. For example, let's say that each row has two ID numbers, and a data value. The first ID number may occur once, twice, or not be included, and the second ID number is either 1 or -1. The data value is not important, but for the sake of this example, we'll say it's an integer. For each pair of ID numbers, there can only be one data value, so if I have a data point where the ID's are 10 and 1, there won't be another 10 and 1 row with a different data value. Similarly, in the other table, the data point with ID's 10 and 1 will be the same as in the first table. I want to be able to select the rows that exist in both tables for the sake of changing the data value in all of the rows that are in both. My command for MySQL so far is as follows:
SELECT DISTINCT * FROM schema.table1
WHERE EXISTS (SELECT * from schema.table1
WHERE schema.table1.ID1 = schema.table2.ID1
and schema.table1.ID2 = schema.table2.ID2);
I want to be able to have this code select all the rows in table1 that are also in table2, but allow me to edit table1 values.
I understand that by creating a union of the two tables, I can see the rows that exist in both tables, but would this allow me to make changes to the actual data values if I changed the values in the merged set? For example, if I did:
SELECT DISTINCT * FROM schema.table1 inner join schema.table2
WHERE schema.table1.ID1 = schema.table2.ID1
schema.table1.ID2 = schema.table2.ID2;
If I call UPDATE on the rows that I get from this query, would the actual values in table1/table2 be changed or is this union just created in dynamic memory and I would just be changing values that get deleted when the query is over?
Update as follows:
UPDATE table1 SET data = whateverupdate
WHERE ID1 IN (SELECT ID1 from schema.table1
WHERE schema.table1.ID1 = schema.table2.ID1
and schema.table1.ID2 = schema.table2.ID2);
In your inner select statement, you cannot do a select * you'll have to select a particular column. This should work because your inner select finds the row in question and feeds it to your update statement. That being said, your inner select has to return the right row you need, else, the wrong row will be updated. Hope this helps.
I don't know much about MySQL but I have to do sth. with this nice thing. :)
I have 1 Table with 2 ID Fields in it (ID and REFID).
I only want to select the ID's which are not between other ID to REFID.
Row 1: ID = 1 and REFID = 15
Row 2: ID = 17 and REFID = 20
Row 3: ID = 19 and REFID = 25
I only want Row 1 and 2 in my result.
because Row 3 is crossing Row 2.
Sorry for my bad explanation,
I hope you know what I want to know. :)
This is based on the general pattern for finding a row in a table that doesn't match another table, as in Return row only if value doesn't exist. But in this case the two tables are the same table, and the match is by checking for id being between id and RefID in the other row.
SELECT t1.*
FROM yourTable AS t1
LEFT JOIN yourTable AS t2 ON t1.id > t2.id AND t1.id < t2.RefID
WHERE t2.id IS NULL
DEMO
For this, you should use MySql procedures. You can find the tutorial here.
Are you doing this with PHP?
If so maybe something like this...
- create a query to return the desired columns of the table in an array ORDER by id
- then create a loop to start with get the records starting with the id equal to the lowest id number
- and repeat the loop until you have retrieved the record with the highest id number you desire.
or use WHERE in the query to specify the id range you want returned.
One of these approaches should get you there... I think :-)
I want to fetch latest entries in a table that is containing more than 1,000,000 entries. I am using this query for an instance
SELECT id FROM tablea WHERE flag = "N" ORDER BY id LIMIT 510045,200;
and it gives me entries starting from 510045 and ending at 510245. Can MYSQL have something where I can get entries starting from 510245 to 510045. I mean fetching the data from the last and I don't want to fetch only 200 entries.
You should ORDER BY desc and, if you want, LIMIT for define how many entries you want.
Example:
SELECT id FROM tablea WHERE flag = "N" ORDER BY id DESC;
-- this will help to find the last entries
But if you want to have the latest entries that you didn't get in last query, you should always hold the value of the last ID, and use it as reference to next check.
Example (Supposing the last ID of the last query execution was 55304):
SELECT id FROM tablea WHERE flag = "N" WHERE id > 55304 ORDER BY id DESC;
If what you want is rows where the id is greater than 510245 just use the where condition
Select * FROM table WHERE flag = 'n' AND id > 510245
This should do it
As i understand your requirement . you may try it.
Select * FROM table WHERE flag = 'N' AND id > 510245 ORDER BY id
One more thing here is
The version i was working on was not supporting subquery containing LIMIT. So, #strawberry Thanks for giving me the hint to solve the question. But I used this sub query as inner join table(explained below)
SELECT id FROM tablea AS T1
INNER JOIN (SELECT id FROM tablea WHERE flag = "N" ORDER BY id LIMIT 510045,200) AS T2
WHERE T2._id = T1._id ORDER BY T2._id DESC;
This gave me the required results. Thanks everyone for your help !!
I'm trying to develop a script to update the running total within a table:
update transactions set running_total = (select sum(amount) from transactions t2 where t2.sequence_number <= transactions.sequence_number)
running_total = the cumulative sum of the amount column
sequence_number = the order in which transactions occurred: 1,2,3,4,5...
MySQL is expectedly showing error You can't specify target table 'transactions' for update in FROM clause
How can I re-write this script without using variables (i.e., by relying only on joins, etc.)
You can do the following:
Execute the following query:
SELECT t.id, t.total,
(SELECT SUM(total) FROM transactions WHERE id <= t.id) AS running
FROM transactions t;
Store the output in a temp table (here is the documentation)
Write an update query that will update the records from this table
UPDATE transactions t
SET running_total = (SELECT running FROM temp WHERE id = t.id);
Delete the temp table.
For the new INSERTs, you can write the logic in your application (or a BEFORE INSERT trigger) to calculate running total before a row gets inserted.
Here is the SQL Fiddle.
It is absolutely beyond my ideas why the following query is not working:
DELETE orig FROM revision AS orig JOIN (
SELECT id
FROM revision
GROUP BY id
HAVING COUNT(*) > 1
) AS joined ON orig.id = joined.id
WHERE orig.id=1
ORDER BY orig.delta ASC
LIMIT 1
The error is thrown on line 8, so the ORDER BY clause. However, I cannot see anything wrong with it (the table revision does have a column called delta). Moreover, changing DELETE orig to SELECT * results in a flawlessly working command.
Is it possible that the delta-column isn't loaded? Or what is causing this error?
edit
Ah okay, I didn't know that you cannot use ORDER BY with multiple rows on a DELETE query.
Well, what I am trying to accomplish is that I delete one row in my table, which has an id that occurs more than once (will be 5 in production) and has the lowest delta of all rows with that id.
I.e. I have two rows in the revision table, both with the same id. I now want to delete that row which has the lowest delta of the two. This should be scalable, so that I delete all rows (with the same id) but one (the one with the highest delta).
You can't use ORDER BY if you have multiple tables in your DELETE statement
I think this is what you are trying to do. It will delete only 1 row only if the (id,delta) combination has a unique constraint:
DELETE orig
FROM revision AS orig
JOIN
( SELECT MIN(delta) AS delta
FROM revision
WHERE id = 1
HAVING COUNT(*) > 1
) AS joined ON orig.delta = joined.delta
WHERE orig.id = 1 ;
To delete all rows (with same id) except the (say 5) rows with highest delta, you can use:
DELETE orig
FROM revision AS orig
JOIN
( SELECT delta
FROM revision
WHERE id = 1
ORDER BY delta DESC
LIMIT 1 OFFSET 4 -- select the 5th highest
) AS joined ON orig.delta < joined.delta -- then find the lower than that
WHERE orig.id = 1 ;