I have this wrong query:
update product prod set
prod.id = (select fur.p_id
from furnisher fur
where prod.row number = fur.row number
)
What I wanna do is to set the p_id from the first row of the table furnisher to the id of the first row of the table product.
the same for the other elements...
I didn't find the exact syntax to execute my query (my dbms is mySql)
For example I have:
product |id|name |....
|1 |prod1|
|2 |prod2|
....
fournitsher p_id|activation_date|status|...
500 |'01-01-205' | true |
1000|'01-01-205' | true |
....
my table product should contain now :
product |id |name |....
|500 |prod1|
|1000 |prod2|
Since you only want to do it for the first row, you can achieve this with limit. Note that since you want a first row, it should be given an order, else it is illogical as we don't really know what "first" mean. So order it by whatever you want
update furnisher a
join (select p_id
from furnisher
order by any_field
limit 1) b using(p_id)
set a.p_id = (select id
from product prod
order by any_field
limit 1);
I tried this solution and it solves my problem :)
CREATE PROCEDURE ROWPERROW()
BEGIN
DECLARE n INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
SELECT COUNT(*) FROM product INTO n;
SET i=0;
WHILE i<n DO
update product set id = ( select p_id from furnisher LIMIT i,1);
SET i = i + 1;
END WHILE;
End;
;;
then I call my procedure
call ROWPERROW();
Related
I have 3 Mysql tables and I want to make one of the fields generated from multiplying two fields from two different tables. These are my tables:
ITEMS
id_item | price
1 | 20
2 | 30
3 | 50
DETAIL TRANSACTIONS
id_trans(fk) | id_item | total_items
1 | 1 | 1
1 | 2 | 1
1 | 3 | 1
TRANSACTIONS
id_trans | total_price
1 | 100
A total price field inside TRANSACTIONS is what I wanted, and I have tried making a trigger like:
CREATE TRIGGER total_price
AFTER INSERT ON detail_transactions
FOR EACH ROW
UPDATE transactions
SET transactions.`total_price`=
(SELECT SUM(items.'price'*detail_transactions.'total_items')
FROM items
JOIN detail_transactions
ON items.'id_item'= detail_transactions.`id_item`)
WHERE transactions.`id_trans` = NEW.`id_trans`;
But the result is not what I wanted. Any help will be appreciated!
Key words are FOR EACH ROW - ie update 1 row at a time..And do not assume transactions exists test and create if need be
drop trigger if exists t;
delimiter $$
create trigger t after insert on detail_transactions
for each row begin
if not exists (select 1 from transactions t where t.id_trans = new.id_trans) then
insert into transactions
select new.id_trans,new.total_items * price
from items
where items.id_item = new.id_item ;
else
update transactions join items on items.id_item = new.id_item
set total_price = total_price + (new.total_items * price);
end if;
end $$
CREATE TRIGGER tr_ai_update_total_price
AFTER INSERT
ON detail_transactions
FOR EACH ROW
REPLACE INTO transactions (id_trans, total_price)
SELECT NEW.id_trans, SUM(items.price * detail_transactions.total_items)
FROM items
JOIN detail_transactions USING (id_item)
WHERE transactions.id_trans = NEW.id_trans;
This query assumes that transactions (id_trans) is defined as UNIQUE (maybe PRIMARY KEY).
If the row for this id_trans already exists it will be replaced with new values. If it not exists then it will be inserted.
The trigger creation statement contains 1 statement, so neither BEGIN-END nor DELIMITER needed.
I want to update column value of any(provided) row value.
Table_A
+--------+-----------+
| num | text |
+--------+-----------+
| 1 | one |
| 2 | two |
| 3 | dont |
| 4 | four |
| 5 | five |
+--------+-----------+
I want to update 3rd row value. Something like this:
update Table_A set `text`='three' Limit 2,1
update Table_A set `text`='three' where 1 Limit 2,1
Assuming your "3rd row" has num column with value 3, you may try this:
UPDATE `Table_A` SET `text` = 'three' WHERE `num` = 3;
"I want to update 3rd row value" -- there is no "third row". The order in which rows are returned should be regarded as random (even if it usually isn't) unless you specifically add an ORDER clause.
Even then, you cannot refer to a row by its position; the query that effects the UPDATE has no way of knowing which row you're referring to from the previous SELECT. You would need some function referring to the row being selected; some SQL dialects have row_number() function, similar to old Clipper RECNO. See also here.
What you can do is choose some identifying value and use that to refer to the row(s) you want:
UPDATE `Table_A` SET `text` = 'three' WHERE `num` IN ( 3 );
UPDATE `Table_A` SET `text` = 'three' WHERE `text` IN ( 'dont' );
More information on updating a table based on a ranking (which I guess is what you're looking for) can be found on the manual page, see the notes about 'recno'.
UPDATE table_name
SET column1=value1,column2=value2,...
WHERE some_column=some_value;
UPDATE `Table_A` SET `text` = 'three' WHERE `num` = 3;
I think you expected like this
UPDATE Table_A t1 join (SELECT num,(#Row := #Row + 1) AS row_number
FROM Table_A, (SELECT #Row:=0) as row
) t2 ON t1.num=t2.num
SET t1.text='three' where t2.row_number='3'
I need to update rows by their number(not AI ID, cause some of the rows may will be removed). How can I do this?
I mean something like this:
UPDATE cars SET idx = value WHERE row_number = i
I would do this in a 'for' statement, and i is the integer of my statement. So I would update every row in the statement.
Sorry for my bad english, and thanks!
Here's a pure MySQL solution:
/*test data*/
create table foo (id int auto_increment primary key, a int);
insert into foo (a) values (10), (11), (12);
/*update statement*/
update foo
set a = 5
where id = (
select id from (
select id, #rownum:=#rownum + 1 as rownumber
from foo, (select #rownum:=0) vars order by id
) sq where rownumber = 2
);
Results in:
| ID | A |
-----|----|--
| 1 | 10 |
| 2 | 5 |
| 3 | 12 |
Feel free to ask if you have any questions about this.
Also, note the order by id in there. It's important, cause in a database there is no first or last row. Without an order by clause theoretically there could be each time a different result.
You can also see it working live here in an sqlfiddle.
i don't know this about mysql but you can do this in php
$row_number=? ;//the row no of mysql you want to change the id
$id=? ;//the new id
mysql_connect //do it yourself
$query="select 8 from tablename"; //the query
$result=mysql_query($qyery,$conn);
$count=0;
while($row=mysql_fetch_array($result)) // fetch each row one by one an put data in array $row
{
$count++; //increment count means the no of rows are incermented
if($count==$rownumber) //the row where you want to edit the id
{
$query1="update tablename set id='".$id."' where id=".$row["id"]; //new query on that particular row
$result1=mysql_query($query1,$conn);
}
}
this will work , just modify this code according to your use
MySQL. Two columns, same table.
Column 1 has product_id
Column 2 has category_ids (sometimes 2 categories, so will look like 23,43)
How do i write a query to return a list of product_id, category_ids, with a seperate row if there is more than 1 category_id associated with a product_id.
i.e
TABLE:
product_id | category_ids
100 | 200,300
101 | 201
QUERY RESULT: Not trying to modify the table
100 | 200
100 | 300
101 | 201
EDIT: (note) I don't actually wish to manipulate the table at all. Just doing a query in PHP, so i can use the data as needed.
Your database table implementation seems bad designed, however in your case what you need would be a reverse function of GROUP_CONCAT, but unfortunately it doesn't exist in MySQL.
You have two viable solutions :
Change the way you store the data (allow duplicate on the product_id field and put multiple records with the same product_id for different category_id)
Manipulate the query result from within your application (you mentioned PHP in your question), in this case you have to split the category_ids column values and assemble a result set by your own
There is also a third solution that i have found that is like a trick (using a temporary table and a stored procedure), first of all you have to declare this stored procedure :
DELIMITER $$
CREATE PROCEDURE csv_Explode( sSepar VARCHAR(255), saVal TEXT )
body:
BEGIN
DROP TEMPORARY TABLE IF EXISTS csv_Explode;
CREATE TEMPORARY TABLE lib_Explode(
`pos` int unsigned NOT NULL auto_increment,
`val` VARCHAR(255) NOT NULL,
PRIMARY KEY (`pos`)
) ENGINE=Memory COMMENT='Explode() results.';
IF sSepar IS NULL OR saVal IS NULL THEN LEAVE body; END IF;
SET #saTail = saVal;
SET #iSeparLen = LENGTH( sSepar );
create_layers:
WHILE #saTail != '' DO
# Get the next value
SET #sHead = SUBSTRING_INDEX(#saTail, sSepar, 1);
SET #saTail = SUBSTRING( #saTail, LENGTH(#sHead) + 1 + #iSeparLen );
INSERT INTO lib_Explode SET val = #sHead;
END WHILE;
END; $$
DELIMITER ;
Then you have to call the procedure passing the array in the column you want to explode :
CALL csv_explode(',', (SELECT category_ids FROM products WHERE product_id = 100));
After this you can show results in the temporary table in this way :
SELECT * FROM csv_explode;
And the result set will be :
+-----+-----+
| pos | val |
+-----+-----+
| 1 | 200 |
| 2 | 300 |
+-----+-----+
It could be a starting point for you ...
Let's say I have a table like this:
name |order_id
=======================
first_record | 0
second_record | 0
third_record | 0
[...]
I want to update just order_id with an incremented value (not sure how to put this correctly in english - feel free to edit with a better description). See expected output below:
name |order_id
=======================
first_record | 1
second_record | 2
third_record | 3
[...] | n
I know how to do this either by using a script in some programming language or a sql procedure, both solution involve looping the whole table.
You can update table:
SET #oo = 0;
UPDATE table SET `order_id`=#oo:=#oo+1 ORDER By something;
Or just get order_id as returned row number while selecting:
SET #oo = 0;
SELECT name, #oo:=#oo+1 order_id FROM table ORDER By something;
Do you mean something like this? The question is not that clear.
DECLARE #order_id int
SET #order_id = 0
UPDATE #tmp_Users
SET #order_id = order_id = #order_id + 1