How can I perform this MySql Statement in a loop - mysql

I would write my cmd line statements more sophistically. How can this be done by using a loop?
update refs set custom_7 = '';
update refs set custom_7='1' where custom_7 = '' limit 220 ;
update refs set custom_7='2' where custom_7 = '' limit 220 ;
update refs set custom_7='3' where custom_7 = '' limit 220 ;
...
update refs set custom_7='100' where custom_7 = '' limit 220 ;
thanks a lot.

If there is a column, like an id, that defines the order of the rows by which you want to update the rows, use ROW_NUMBER() window function to rank the rows and join to the table:
WITH cte AS (SELECT *, ROW_NUMBER() OVER (ORDER BY id) rn FROM refs)
UPDATE refs r
INNER JOIN cte c ON c.id = r.id
SET r.custom_7 = (c.rn - 1) DIV 220 + 1
WHERE c.rn <= 100 * 220; -- remove the WHERE clause if there is actually no limit to the values of custom_7
If there is no column like the id, you may remove ORDER BY id from the OVER() clause of ROW_NUMBER(), but then the rows will be updated arbitrarily.
See a simplified demo.

You can try something like this (please replace datatype(length) with the type of custom7)
DECLARE #count INT;
SET #count = 1;
WHILE #count<= 100
BEGIN
UPDATE refs SET custom_7 = CAST(#count AS **datatype(length)**) WHERE custom_7 = '' LIMIT 220;
SET #count = #count + 1;
END;

Related

Convert MySQL syntax to PostgreSQL

I use this code in MySQL to order by 'anotherColumn' and then get the row number of 'myColumn' and then I perform a calculation and set 'myColumn' to the result:
SET #c = (SELECT COUNT(*) FROM myTable); SET #rownum = 0; UPDATE myTable SET myColumn = #c * (#rownum:= 1 + #rownum) ORDER BY anotherColumn DESC LIMIT 100000;
I'm trying to achieve the same thing in Postgresql but am getting a lot of errors. I have:
SET c = (SELECT COUNT(*) FROM myTable); SET rownum = 0; UPDATE myTable SET myColumn = c * (rownum:= 1 + rownum) ORDER BY anotherColumn DESC LIMIT 100000;
.. but it gives me an error at the first parenthesis. If I remove those parenthesis like this:
SET c = SELECT COUNT(*) FROM myTable; SET rownum = 0; UPDATE myTable SET myColumn = c * (rownum:= 1 + rownum) ORDER BY anotherColumn DESC LIMIT 100000;
.. then it gives me an error at the SELECT. If I just set c to equal 0, I get an error way down at the ORDER. Does anyone know how to convert my code from MySQL to PostgreSQL?
This "pattern" in MySQL is typically used to work around the absence of window function.
You don't need variables in Postgres to achieve something like that:
update my_table
set my_column = t.cnt + t.rn
from (
select pk_column,
(select count(*) from my_table) as cnt,
row_number() over (order by another_column) as rn
from my_table
limit 100000
) t
where t.pk_column = my_table.pk_column;
Where pk_column is the primary key column of your table. If you have more than one PK column, you need to use all of them.

MySQL / MariaDB place COUNT(*) in equation

I'm trying to get the number of rows in a table or column and place that value inside an equation, like this:
UPDATE myTable
SET myCalculatedColumn = COUNT(*) / (#rownum:= 1 + #rownum)
WHERE 0 = (#rownum:=0)
Unfortunately, I get an error 1111 "Invalid use of group function". I've also tried:
SET #c = COUNT(*);
UPDATE myTable
SET myCalculatedColumn = #c / (#rownum:= 1 + #rownum)
WHERE 0 = (#rownum:=0)
But this produces the same error.
How can I place COUNT(*) (or a programmatically equivalent operation) into an equation?
Join with a subquery that gets the count. You can also initialize the #rownum variable there as well.
UPDATE myTable AS t
CROSS JOIN (SELECT COUNT(*) AS count, #rownum := 0 FROM myTable) AS c
SET myCalculatedColumn = count / (#rownum := 1 + #rownum)
If you don't want to do a cross join, you can use the subquery when setting #c. You just have to tell COUNT(*) what table to count from.
SET #c = (SELECT COUNT(*) FROM myTable);
SET #rownum = 0;
UPDATE myTable
SET myCalculatedColumn = #c / (#rownum:= 1 + #rownum);
Note that the order that it assigns to myCalculatedColumn will be arbitrary and unpredictable unless you also have an ORDER BY clause.

Problem with increment variable and stored procedure to check duplicates

I have problem with my procedure. I have table oferty_in which contain fields (id, status, ..., id_om). I want procedure which check if exist rows with the same id_om.
If exist, delete rows where status = 'N' (N - new).
My procedure almost works, but i have problem with iterate in loop. Every time I run my procedure ,procedure delete a half of rows. I don't know where is problem...
DELIMITER //
CREATE PROCEDURE check_duplicates_oferty_in()
BEGIN
DECLARE n INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
DECLARE v_id_del BIGINT;
SELECT count(*) INTO n FROM oferty_in where status_oferty = 'N';
SET i=0;
WHILE i<n DO
IF EXISTS (SELECT id_om FROM oferty_in group by id_om having count(*) >= 2 LIMIT i,1) THEN
SELECT id_om INTO v_id_del FROM oferty_in group by id_om having count(*) >= 2 LIMIT i,1;
DELETE from oferty_in where id_om = v_id_del and status_oferty = 'N';
END IF;
SET i=i+1;
END WHILE;
END
//
I try also:
IF EXISTS (SELECT id_om FROM oferty_in group by id_om having count(*) >= 2 LIMIT i,1) THEN
SELECT id_om INTO v_id_del FROM oferty_in group by id_om having count(*) >= 2 LIMIT i,1;
DELETE from oferty_in where id_om = v_id_del and status_oferty = 'N';
SET i=i+1;
ELSE
SET i=i+1;
END IF;
But it's the same.
Every time half of rows. I use counter 'i' and while loop to iterate row by row on rows in oferty_in when status = 'N'. Anyone have a idea what I did wrong? Thanks for help and time.
You seem to want to delete rows with status = 'N' when id_om is duplicated.
I want procedure which check if exist rows with the same id_om. If exist, delete rows where status = 'N' (N - new).
Non-working code doesn't generally help explain logic, so this is what I am going by.
You definitely do not need a looping construct for this, nor a cursor:
delete o
from oferty_in o join
(select o2.id_om
from oferty_in o2
group by o2.id_om
having count(*) > 1 and sum(status = 'N') > 0
) o2
on o.id_om = o2.id_om
where o.status = 'N';

How to order when update in zend

How can i order when update multi row in Zend ?
For example, when I updated my table as follows :
SET #pos = 0 ;
UPDATE table SET sort = ( SELECT #pos := #pos + 1 ) where status = 1 ORDER BY id ASC;

mysql update a column with an int based on order

Lets say I have these columns
uniqueID|Money|Quantity|MoneyOrder|QuantityOrder
1|23|12||
2|11|9||
3|99|100||
What I want to do is update MoneyOrder and QuantityOrder based on the value of ORDER BY.
So the results would be:
uniqueID|Money|Quantity|MoneyOrder|QuantityOrder
1|23|12|2|1
2|11|90|1|2
3|99|100|3|3
I want the update to operate like an identity column without actually making it an identity column. I know that I could just order by 'x' and the order would be the result but I want to generate a report where you can see the item line by line.
Is something like this possible update mytable set Moneyorder = 'imnotsure' order by MoneyOrder asc ?
SET #rownumber = 0;
update mytable set Moneyorder = (#rownumber:=#rownumber+1)
order by MoneyOrder asc
or to do it in a single query you can try
update mytable target
join
(
select id, (#rownumber := #rownumber + 1) as rownum
from mytable
cross join (select #rownumber := 0) r
order by MoneyOrder asc
) source on target.id = source.id
set Moneyorder = rownum
See answers to this question:
Updating column so that it contains the row position
SET #counter = 0;
UPDATE
my_table
SET MoneyOrder = #counter := #counter + 1
ORDER BY Money;
SET #counter = 0;
UPDATE
my_table
SET QuantityOrder = #counter := #counter + 1
ORDER BY Quantity;