mysql update a column with an int based on order - mysql

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;

Related

How can I perform this MySql Statement in a loop

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;

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.

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;

Select only unique records

I'm trying to select all records in a table, but hide duplicate rows. So if 2 rows are completely the same (except for the auto increment ID of course), only 1 should be shown.
I thought this had to be done with distinct, but it still give me duplicate rows.
SELECT DISTINCT *
FROM tbllulog
WHERE lulogluserial = $commandlu
ORDER BY `tbllulog`.`tbllulogid` DESC
I also tried this:
SELECT DISTINCT lulogtimestamp,
lulogmoveemployee,
lulogsource,
lulogaction,
lulogluoutput0status,
lulogluinput0status
FROM tbllulog
WHERE lulogluserial = $commandlu
ORDER BY `tbllulog`.`tbllulogid` DESC
But this also give me duplicates
Anyone can point me out what i'm missing?
thanks!
Use DISTINCT and GROUP BY and add the tbllulogid to the SELECT
SELECT DISTINCT tbllulogid,
lulogtimestamp,
lulogmoveemployee,
lulogsource,
lulogaction,
lulogluoutput0status,
lulogluinput0status
FROM tbllulog
WHERE lulogluserial = $commandlu
GROUP BY `tbllulog`.`tbllulogid`
ORDER BY `tbllulog`.`tbllulogid` DESC
Try like this
DECLARE #type varchar(50);
DECLARE #num int;
SET #type = '';
SET #num = 1;
SELECT * FROM
(
SELECT lulogtimestamp,
lulogmoveemployee,
lulogsource,
lulogaction,
lulogluoutput0status,
lulogluinput0status
#num := if(#type = lulogmoveemployee, #num + 1, 1) as row_number,
#type := lulogmoveemployee As Dummy
FROM tbllulog
WHERE lulogluserial = $commandlu
ORDER BY `tbllulog`.`tbllulogid` DESC
) T WHERE row_number = 1