I have a problem updating a table with new values from a list.
My data looks like this:
id value_1 value_2
1 11 21
2 32 41
3 43 84
...
I already wrote the column id and value_1 with an INSERT command in the table. At that step, I cannot write the value_2 column as I still need to calculate it, so I want to update the table later with an array of values of the value_2 column.
I would like to have a code something like this:
UPDATE table_name SET value_2 = (21,41,84) WHERE id IN (1,2,3)
Unfortunately, it's not possible like this to SET value_2 from a list, it works only with single values.
I got a workaround with writing a for loop over the whole UPDATE query, but this was too slow for my program.
Anyone has a suggestion how I could get this working?
The whole query is performed with Python.
It can be done with one single UPDATE, using a case expression to set the wanted value. Something like this:
UPDATE table_name
SET value_2 = case id when 1 then 21
when 2 then 41
when 3 then 84
end
WHERE id IN (1,2,3)
However, I don't know if it will make any performance difference.
After trying different things I could find a solution to update values of table fast using value lists as input.
I orientated on the idea presented in this question (https://stackoverflow.com/a/3466/7997169) and modified it to deal with lists.
As input I have lists like this:
id = [1, 2, 3, ... ]
value_1 = [11, 32, 41, ... ]
value_2 = [21, 41, 84, ... ]
Using the Python MySQL connector I could write the whole update loop into one query command. Therefore I wrote the data from the lists into a string looking like this:
VALUES (1,11,21),(2,32,41),(3,41,84),....
The total code looks like this:
for i in range(0,len(id),1):
a = '(' + str(id[i]) + ',' + str(value_1[i]) + ',' + str(value_2[i]) + ')'
b = ','
if i < (len(id)-1):
c = c + a + b
else:
c += a
update_cell_info = ("INSERT INTO table (id, value_1, value_2)"
"VALUES %s" % c +
"ON DUPLICATE KEY UPDATE "
"value_1=VALUES(value_1),"
"value_2=VALUES(value_2)"
";")
cursor.execute(update_cell_info)
In the end this procedure is over 10x faster than the previous one where I used a for loop to iterate the update process with new variables.
Related
I have a sequence of 20 numbers from 0 to 2, I want to compare this string with other sequences saved in my database, the problem is that the lenght of the strings saved on the database fluctuates.Also the comparison needs to be done from the end to the start.
Example of what I want:
20 digits string:
'1,1,2,1,2,1,0,1,2,1,2,1,0,1,2,1,1,1,2,1'
couple of strings saved in the database:
1 - '1,1,2,1'
2 - '2,1,2,2,2,2'
3 - '2,1'
4 - '1,1,2,1,2,1'
In this case the query would return the 1 and 3 only
create table mytable ( s varchar(60) );
insert into mytable values
('1,1,2,1'),
('2,1,2,2,2,2'),
('2,1'),
('1,1,2,1,2,1');
set #x = '1,1,2,1,2,1,0,1,2,1,2,1,0,1,2,1,1,1,2,1';
select s from mytable
where right(#x, length(s)) = s;
Output:
s
1,1,2,1
2,1
Fiddle: https://www.db-fiddle.com/f/r5m2hPbnmUu5VQfYvMVtir/0
You could use a LIKE trick here. For example, to check for the first string 1,1,2,1:
SELECT *
FROM yourTable
WHERE ',1,1,2,1,2,1,0,1,2,1,2,1,0,1,2,1,1,1,2,1,' LIKE '%,1,1,2,1,%';
I use mysql to deal some data use multi-thread, first I search the data use id range, like:
select id
from xxx
where id between 1 and 1000
and accountant_time = '2021-05-31 00:00:00'
and enter_accounts_state = 1
and enter_ce_state = 2
and ebs_summary_state = 2
and is_del = 0
result id like '1, 2, 3, 4, 5, ... 1001'.
and second I will delete these match data with addtional condition confirm_state from table like sql below:
DELETE
FROM xxx
WHERE confirm_state = 3
AND id IN ( 1, 2, 3, 4, ..., 1001);
All of the id range no intersection。
I found that some thread need return 1001 rows, but only returned the first row,
I tried several times use same code and same data, but the left data also not same, the common feature is only return first row of that batch count which need return all。
When I add for update for the select sql, it works normal,
How can I understand what happens?
So I have two columns from two different databases that I would like to link.
Problem is that my first column outputs the numbers with this format "1 789 987" and my second column outputs the data "0000000001789987"
How can I write my WHERE sql forumla to idententify these as matching?
Ok so I pulled out the qrys to excel to provide you with more information.
Here are the different tables.
Looks like Tbl2 has NUM column set to text. And even though the QRY in the program gave spaces to the numbers in Tbl1 it looks like the qry removed them shrug
SELECT *
FROM "Tbl1","Tbl2"
WHERE "Tbl1"."num" = "Tbl2"."num"
AND "Tbl1"."Date" BETWEEN '2019-01-21' AND '2019-01-25'
I hope the information became abit clearer. I'm new to SQL and Stackoverflow, i'll try and improve my questions information in the future.
Well, to transform format 1 to format 2 you can try something like this :
set #format1 = "1 789 987";
set #format2 = "0000000001789987";
select LPAD(REPLACE(#format1, ' ', ''), 16, "0") as format1, #format2 as format2
Output is :
====================================
format1 | format2
====================================
0000000001789987 | 0000000001789987
This way format1 looks like format2 if you test it. The REPLACE remove the ' ' and the LPAD will fill the string with 0 untill the string is 16 char length like the format2.
So you can use this in you WHERE condition :
...WHERE LPAD(REPLACE(your_first_column, ' ', ''), 16, "0") = your_other_column
Now you can try to transform both column in int too, you didn't provide lot of information about those format so hard to find the best solution !
This cast may fit for you:
NOTE: tbl1 contains ids like: 1 789 987
select *
from tbl1 join tbl2 on (
cast( -- casts to integer
replace(tbl1.text_id, ' ', '') -- removes whitespaces
as int) =
tbl2.numeric_id -- join on second table
)
In any case please provide sample data and a testable example what you did and the results you need
If I take a value of 12345 from MySQL and I want to display that at the front end as Mo Tu We Th Fr, how can I do that allowing for all possible combinations?
I could write a case statement but there are going to be many hundreds of combinations to cover all possible values.
The value will be anything from 1 to 7 characters long using between digits between 1 and 7 and could be in any order so 3417 should read We Th Mo Su whilst 645 should read Sa Th Fr and so on. I cannot do this in the application so have to try and figure out how to do it in MySQL. These are stored in MySQL as a varchar in a single column.
Can I use replace multiple times in the same select so something like:
REPLACE(REPLACE(REPLACE(field, '1', 'Mo '), '2', 'Tu'), '3', 'We')
or is there another way?
You can create a helper table that contains 2 columns :
1, su
2, mo
3, ...
then just join the day number to get the second column of the helper table.
If all you want to do is display this in a fronend, you can have a "dictionary" to translate the values.
Lets say for example you have a Table in the structure
tl_days
__________
id | alias
And we have some data such as
id: 1, alias : Mon
id: 2, alias : Tue
We can run a simple query to check the id against an array of numbers.
SELECT alias FROM 'tl_days' WHERE id in (1,2,3,4);
Will return the days as your abbreviations.
You should not write replace for all the values if there are multiple of them, Instead create a mapping table 1|su,2|mo ..., Then use join to fetch the 'su','mo' values from the mapping table
First you would need to ensure that the table schema data matches. If changing from numeric value to text value is acceptable.
Update table_name set column_name =
(
CASE
when column_name = 1 then 'Mo'
when column_name = 2 then 'Tu'
when column_name = 3 then 'We'
when column_name = 4 then 'Th'
when column_name = 5 then 'Fr'
End
);
Here is an SQL FIDDLE displaying such a change.
iam having table like this
id name sol_id
1 abc 2,5,8
2 dt 5,9,10
here i want to add some value(10) to id=1 of sol_id,so value 10 will be added with id=1 and at the same time value 10 of id=2 replace with some empty value i want output like this
id name sol_id
1 abc 2,5,8,10(here updating)
2 dt 5,9 (10 removing)
i wrote query like this but its performs one operation not both
UPDATE my_table SET sol_id=REPLACE(sol_id,',10,',',')
and sol_id = Concat(sol_id, ',', 10) where id = 1
is it possible? Thanks in advance
It is possible, but clunky.
Basically you would do
UPDATE table SET SET field = CASE id
WHEN 1 THEN <formula for the case of id=1>
WHEN 2 THEN <formula for the case of id=2>
END
WHERE ID IN (1, 2);
There's no great advantage over running several queries inside a TRANSACTION and, if necessary, a suitable lock on the table.