I have this table seller whose columns are
id mobile1
1 787811
I have another table with same columns ,I just want to update the mobile1 field from this table with the values from other table say "copy".
I have written this query
UPDATE seller
SET mobile1 = (
SELECT SUBSTRING_INDEX(mobile1, '.', 1)
FROM copy)
WHERE 1;
I am getting this obvious error when I run it.
Sub-query returns more than 1 row ,
Any way to do this??
You need condition which will be using to select only one row or you should use LIMIT:
UPDATE seller
SET mobile1 = (
SELECT SUBSTRING_INDEX(mobile1, '.', 1)
FROM copy
LIMIT 1)
WHERE id = 1;
You can constrain the number of rows returned to just one using MySQL limit.
UPDATE seller SET mobile1=(SELECT SUBSTRING_INDEX(mobile1,'.',1)
FROM copy LIMIT 1)
WHERE id=1;
If anyone who is looking for the possible answer here is what I did,I created a procedure with while loop.
DELIMITER $$
CREATE PROCEDURE update_mobile(IN counting BIGINT);
BEGIN
declare x INT default 0;
SET x = 1;
WHILE x <= counting DO
UPDATE copy SET mobile1=(SELECT SUBSTRING_INDEX(mobile1, '.', 1) as mobi FROM seller WHERE id=x LIMIT 1) WHERE id=x;
SET x=x + 1;
END WHILE;
END
AND finally I calculated the number of rows by count(id) and passed this number to my procedure
SET #var =count;
CALL update_mobile(#var);
AND it worked like a Charm...
If you want to copy all data, you can do this :
INSERT INTO `seller` (`mobile1`) SELECT SUBSTRING_INDEX(mobile1,'.',1) FROM copy
Related
How do i update current row value if my previous row are same with current row.
example:
the curent row is 68, previous row is also 68.. i would i like to update current row become 68-20 which is 48.
same for 98-20 = 78.
so that the corrected data will look like:
i have more than 1000 record like this, which cant update the record one by one manually.
update table1 set DIH_QTY_BALANCE=DIH_QTY_BALANCE-DIH_REORDER_QTY
WHERE how to put the previous row same as current on where clause?
Here is the Schema + data:
http://pastebin.com/T1tYDT6Y
too large for sqlfiddle.
any help would be great.
As far as I remember, MySQL has problems to select from the same table in an update statement. And this is what you would have to do, because in order to update a record or not, you'd have to select its previous record from the same table.
So create a temporary table, give it row numbers, then select from it with a self join, to compare each record with its previous record.
create temporary table temp
(
rownum int,
dihistoryid int,
dih_qty_balance int
) engine = memory;
set #num = 0;
insert into temp
select
#num := #num + 1 as rownum,
dihistoryid,
dih_qty_balance
from mytable
order by dihistoryid;
update mytable
set dih_qty_balance = dih_qty_balance - dih_reorder_qty
where dihistoryid in
(
select current.dihistoryid
from temp current
join temp previous on previous.rownum = current.rownum - 1
where previous.dih_qty_balance = current.dih_qty_balance
);
drop temporary table temp;
May be something like this
SELECT DIH_QTY_BALANCE,
(SELECT DIH_QTY_BALANCE FROM example e2
WHERE e2.DIHISTORYID < e1.DIHISTORYID
ORDER BY DIHISTORYID DESC LIMIT 1) as previous_value,
(SELECT value FROM example e3
WHERE e3.DIHISTORYID > e1.DIHISTORYID
ORDER BY DIHISTORYID ASC LIMIT 1) as next_value
FROM example e1
i have a table in my MySQL database which i have added a new column to.
I would like to update this column on every row with a number starting at 20000 going up +1 each time.
i have tried this solution:
UPDATE table1 set new_col = new_col + 1;
but it just updates all rows with the same number
The easy way:
UPDATE table1 t, (SELECT #nr:= 20000-1) tmp
SET t.new_col = (#nr:=#nr+1) ;
I have used this query to solve this:
SET #rank:=20000;
update customer
set accountnumber_new=#rank:=#rank+1
SELECT LAST_INSERT_ID() as id FROM table1
Why does this query sometimes return the last inserted id of another table other than table1?
I call it in Node.js (db-mysql plugin) and I can only do queries.
LAST_INSERT_ID() can only tell you the ID of the most recently auto-generated ID for that entire database connection, not for each individual table, which is also why the query should only read SELECT LAST_INSERT_ID() - without specifying a table.
As soon as you fire off another INSERT query on that connection, it gets overwritten. If you want the generated ID when you insert to some table, you must run SELECT LAST_INSERT_ID() immediately after doing that (or use some API function which does this for you).
If you want the newest ID currently in an arbitrary table, you have to do a SELECT MAX(id) on that table, where id is the name of your ID column. However, this is not necessarily the most recently generated ID, in case that row has been deleted, nor is it necessarily one generated from your connection, in case another connection manages to perform an INSERT between your own INSERT and your selection of the ID.
(For the record, your query actually returns N rows containing the most recently generated ID on that database connection, where N is the number of rows in table1.)
SELECT id FROM tableName ORDER BY id DESC LIMIT 1
I usually select the auto-incremented ID field, order by the field descending and limit results to 1. For example, in a wordpress database I can get the last ID of the wp_options table by doing:
SELECT option_id FROM wp_options ORDER BY option_id DESC LIMIT 1;
Hope that helps.
Edit - It may make sense to lock the table to avoid updates to the table which may result in an incorrect ID returned.
LOCK TABLES wp_options READ;
SELECT option_id FROM wp_options ORDER BY option_id DESC LIMIT 1;
Try this. This is working
select (auto_increment-1) as lastId
from information_schema.tables
where table_name = 'tableName'
and table_schema = 'dbName'
Most easy way:
select max(id) from table_name;
I only use auto_increment in MySQL or identity(1,1) in SQL Server if I know I'll never care about the generated id.
select last_insert_id() is the easy way out, but dangerous.
A way to handle correlative ids is to store them in a util table, something like:
create table correlatives(
last_correlative_used int not null,
table_identifier varchar(5) not null unique
);
You can also create a stored procedure to generate and return the next id of X table
drop procedure if exists next_correlative;
DELIMITER //
create procedure next_correlative(
in in_table_identifier varchar(5)
)
BEGIN
declare next_correlative int default 1;
select last_correlative_used+1 into next_correlative from correlatives where table_identifier = in_table_identifier;
update correlatives set last_correlative_used = next_correlative where table_identifier = in_table_identifier;
select next_correlative from dual;
END //
DELIMITER ;
To use it
call next_correlative('SALES');
This allows you to reserve ids before inserting a record. Sometimes you want to display the next id in a form before completing the insertion and helps to isolate it from other calls.
Here's a test script to mess around with:
create database testids;
use testids;
create table correlatives(
last_correlative_used int not null,
table_identifier varchar(5) not null unique
);
insert into correlatives values(1, 'SALES');
drop procedure if exists next_correlative;
DELIMITER //
create procedure next_correlative(
in in_table_identifier varchar(5)
)
BEGIN
declare next_correlative int default 1;
select last_correlative_used+1 into next_correlative from correlatives where table_identifier = in_table_identifier;
update correlatives set last_correlative_used = next_correlative where table_identifier = in_table_identifier;
select next_correlative from dual;
END //
DELIMITER ;
call next_correlative('SALES');
If you want to use these workarounds:
SELECT id FROM tableName ORDER BY id DESC LIMIT 1
SELECT MAX(id) FROM tableName
It's recommended to use a where clause after inserting rows. Without this you are going to have inconsistency issues.
in my table inv_id is auto increment
for my purpose this is worked
select `inv_id` from `tbl_invoice`ORDER BY `inv_id` DESC LIMIT 1;
How can I store only 10 rows in a MySQL table? The older rows should be deleted when a new row is added but only once the table has 10 rows.
Please help me
You could achieve this with an after insert trigger, delete the row where it is min date. e.g. DELETE FROM myTable WHERE myTimestamp = (SELECT MIN(myTimestamp) FROM myTable) but that could in theory delete multiple rows, depending on the granularity of your updates.
You could have an incrementing sequence, and always just delete the min of that sequence.
The question is why you'd want to do this though? It's a slightly unusual requirement.
A basic example (not validated/executed, I don't have mySQL on this particular machine) would look something like.
CREATE TRIGGER CycleOldPasswords AFTER INSERT ON UserPasswords FOR EACH ROW
set #mycount = SELECT COUNT(*) FROM UserPasswords up where up.UserId = NEW.UserId;
if myCount >= 10 THEN
DELETE FROM UserPasswords up where up.Timestamp = (SELECT min(upa Timestamp) FROM UserPasswords upa WHERE NEW.UserId = upa.UserId) AND NEW.UserId = up.UserId;
END
END;
You can retrieve the last inserted id when your first row is inserted, and store it in a variable. When 10 rows are inserted, delete the row having id < id of the first inserted record. Please try it.
first of all insert all values using your insert query
and then run this query
delete from table_name where (cond) order by id desc limit 10
must specify an id or time in one column
I have a table (ft_ttd) and want to sort it descending (num) and insert rating numbers into rating column.
Initial Table http://dl.dropbox.com/u/3922390/2.png
Something like that:
Result Table http://dl.dropbox.com/u/3922390/1.png
I've created a procedure.
CREATE PROCEDURE proc_ft_ttd_sort
BEGIN
CREATE TEMPORARY TABLE ft_ttd_sort
(id int (2),
num int (3),
rating int (2) AUTO_INCREMENT PRIMARY KEY);
INSERT INTO ft_ttd_sort (id, num) SELECT id, num FROM ft_ttd ORDER BY num DESC;
TRUNCATE TABLE ft_ttd;
INSERT INTO ft_ttd SELECT * FROM ft_ttd_sort;
DROP TABLE ft_ttd_sort;
END;
When I call it - it works great.
CALL proc_ft_ttd_sort;
After that I've created trigger calling this procedure.
CREATE TRIGGER au_ft_ttd_fer AFTER UPDATE ON ft_ttd FOR EACH ROW
BEGIN
CALL proc_ft_ttd_sort();
END;
Now every time when I update ft_ttd table I've got a error.
UPDATE ft_ttd SET num = 9 WHERE id = 3;
ERROR 1422 (HY000): Explicit or implicit commit is not allowed in stored function ortrigger.
Any ideas how to make it work? Maybe this process can be optimized?
Thank you!
The create table statement is an implicit commit, since it's DDL. Basically, the answer is you can't create a table in a trigger.
http://dev.mysql.com/doc/refman/5.0/en/stored-program-restrictions.html
Triggers can't do it
DDL aside, your trigger-based approach has a few difficulties. First, you want to modify the very table that's been updated, and that's not permitted in MySQL 5.
Second, you really want a statement-level trigger rather than FOR EACH ROW — no need to re-rank the whole table for every affected row — but that's not supported in MySQL 5.
Dynamically compute "rating"
So ... is it enough to just compute rating dynamically using a MySQL ROW_NUMBER() workaround?
-- ALTER TABLE ft_ttd DROP COLUMN rating; -- if you like
SELECT id,
num,
#i := #i + 1 AS rating
FROM ft_ttd
CROSS JOIN (SELECT #i := 0 AS zero) d
ORDER BY num DESC;
Unfortunately, you cannot wrap that SELECT in a VIEW (since a view's "SELECT statement cannot refer to system or user variables"). However, you could hide that in a selectable stored procedure:
CREATE PROCEDURE sp_ranked_ft_ttd () BEGIN
SELECT id, num, #i := #i + 1 AS rating
FROM ft_ttd CROSS JOIN (SELECT #i := 0 AS zero) d
ORDER BY num DESC
END
Or UPDATE if you must
As a kluge, if you must store rating in the table rather than compute it, you can run this UPDATE as needed:
UPDATE t
CROSS JOIN ( SELECT id, #i := #i + 1 AS new_rating
FROM ft_ttd
CROSS JOIN (SELECT #i := 0 AS zero) d
ORDER BY num DESC
) ranked
ON ft_ttd.id = ranked.id SET ft_ttd.rating = ranked.new_rating;
Now instruct your client code to ignore rows where rating IS NULL — those haven't been ranked yet. Better, create a VIEW that does that for you.
Kluging further, you can likely regularly UPDATE via CREATE EVENT.