Updating based on intermediate query in SQLAlchemy - sqlalchemy

I'm new to SQLAlchemy and am curious how I would conduct the following UPDATE.
I'm using SQL Expression Language and my version of SQLAlchemy is 1.3.16. I wrote a query that returns [after some filtering and such] the following two columns of a larger table I'll call my_table.
+--------------+-----+
|team_member_id|id |
+--------------+-----+
|3738 |7172 |
|2752 |1016 |
|3738 |7173 |
|3738 |7174 |
|3738 |7175 |
|3738 |7176 |
|3738 |7178 |
|3738 |7177 |
|140 |6679 |
|3568 |7221 |
|3568 |7220 |
...
There's a third column (final_col) of my_table that I'd like to update based on these two columns.
Basically, for each (team_member_id, id) pair above, I'd like to set the row's final_col value to be the team_member_id value. id stays the same; it's just the primary key.
How would I go about doing this?

I found once possible solution in the form of bindparam.
update_executed_by = my_table.update().where(my_table.c.id == bindparam('_id')).values(
final_col=bindparam('_team_member_id'))
bound_params = [{'_team_member_id': row[0], '_id': row[1]} for row in session.execute(get_team_members)]
session.execute(update_executed_by, bound_params)

Related

INSERT INTO WHERE LIKE Condition

I am working on a trigger which needs INSERT INTO with WHERE LIKE logic.
I have one table :
Tabel test;
idDocument = varchar(32) idUnit = varchar(3)
-----------------------------
| idDocument | idUnit |
-----------------------------
| AA/2021/KK | NULL |
| AA/2021/JJ | NULL |
| BB/2021/KK | NULL |
| CC/2021/JB | NULL |
-----------------------------
How to INSERT INTO using WHERE LIKE Condition and myquery still ERROR.
myquery :
INSERT INTO test ('idUnit') Values ('111') WHERE idDocument LIKE
'%KK%'
Normally to update existing rows with a new value you'd do something like this:
UPDATE test SET idUnit='111' WHERE idDocument LIKE '%KK%'
This will not insert data, it will only alter existing data.
Note:
INSERT is specifically for adding new rows of data
UPDATE is exclusively for updating existing rows with new data
You can't conditionally add new rows. You either add them or you don't. You can conditionally update or delete them.
Don't think about it in terms of inserting new data, always think in terms of rows and columns which is how SQL works.

How to update a column with specific data for each row? [duplicate]

I'm trying to update one MySQL table based on information from another.
My original table looks like:
id | value
------------
1 | hello
2 | fortune
3 | my
4 | old
5 | friend
And the tobeupdated table looks like:
uniqueid | id | value
---------------------
1 | | something
2 | | anything
3 | | old
4 | | friend
5 | | fortune
I want to update id in tobeupdated with the id from original based on value (strings stored in VARCHAR(32) field).
The updated table will hopefully look like:
uniqueid | id | value
---------------------
1 | | something
2 | | anything
3 | 4 | old
4 | 5 | friend
5 | 2 | fortune
I have a query that works, but it's very slow:
UPDATE tobeupdated, original
SET tobeupdated.id = original.id
WHERE tobeupdated.value = original.value
This maxes out my CPU and eventually leads to a timeout with only a fraction of the updates performed (there are several thousand values to match). I know matching by value will be slow, but this is the only data I have to match them together.
Is there a better way to update values like this? I could create a third table for the merged results, if that would be faster?
I tried MySQL - How can I update a table with values from another table?, but it didn't really help. Any ideas?
UPDATE tobeupdated
INNER JOIN original ON (tobeupdated.value = original.value)
SET tobeupdated.id = original.id
That should do it, and really its doing exactly what yours is. However, I prefer 'JOIN' syntax for joins rather than multiple 'WHERE' conditions, I think its easier to read
As for running slow, how large are the tables? You should have indexes on tobeupdated.value and original.value
EDIT:
we can also simplify the query
UPDATE tobeupdated
INNER JOIN original USING (value)
SET tobeupdated.id = original.id
USING is shorthand when both tables of a join have an identical named key such as id. ie an equi-join - http://en.wikipedia.org/wiki/Join_(SQL)#Equi-join
It depends what is a use of those tables, but you might consider putting trigger on original table on insert and update. When insert or update is done, update the second table based on only one item from the original table. It will be quicker.

How to compare ids of different formats across databases

Problem: I need a way to compare ids of a type varchar to ids of a type int.
Background: I have a list of ids that almost map to the ids in my table. I have ~10k ids, but I suspect there are only 3-5 variations to clean up.
The tables I'm working with could be simplified as follows. A big table of articles with good ids, and a temp table I've dumped all the dirty ids into. I'd like to update my temp table with the correct id whenever I'm able to make a match
licensing.articles
+----------+
| id (int) |
+----------+
| 1000 |
| 1001 |
| 1002 |
+----------+
tempDB.ids
+-------------------+----------------+
| id_dirty (string) | id_clean (int) |
+-------------------+----------------+
| 1000Z | |
| R1001 | |
| 1002 | |
+-------------------+----------------+
So my first query is the simple version: for records that share the same id between the licensing.articles table and the tempDB.ids table, I want to populate tempDB.ids.id_clean with the good id. (In my example, there is one shared id (1002), but in reality there's probably ~3k of them.)
When I try something like this:
UPDATE tempDB.ids AS dirty
JOIN licensing.articles clean ON clean.id = CAST(dirty.id_dirty as unsigned)
SET dirty.id_clean = clean.id
WHERE isnull(dirty.id_clean);
I get an error message Error : Truncated incorrect INTEGER value: '1000Z'. That makes sense; presumably it is failing to convert '1000Z' to an integer.
So how can I say
FOR ONLY tempDB.ids.id_dirty values that can be successfully cast to an int
SELECT the matching record from licensing.articles
AND copy licensing.articles.id to tempDB.ids.id_clean

mysql update multiplecolumns vs compare values in multiple rows

Okay, talking millions of rows here..
Structure of like
EXAMPLE 1
some_data_before this| x_counter_total | y_counter_total | x_counter_week | y_counter_week | x_counter_year | y_counter_year
--------------------------------------------------------------------------------------------------------------------------------------
some_data_here... | 42142142....... | `241242142..... | 23214124...... | .............. | .............. |` ..............
And every of X and Y events to increment these columns vs this
EXAMPLE 2
table A
some_data_before this| x_counter_total | y_counter_total |
----------------------------------------------------------
some_data_here...... | 42142142....... | `241242142..... |
table B
key_connected_with_table_A | x_event | y_event | occured_timestamp
-------------------------------------------------------------------
id 21...................... | true | false | current_timestamp
My need is this. I need number of X and Y events in some time, past day/week/month/year etc.
My question is that Is it better to update(increment) multiple columns describing the time period i need, like in EXAMPLE 1 or is it better to
on each Event add a Row like in EXAMPLE 2 and then count total VOTES with same ID WHERE occured_timestamp - current_timestamo < TIMESTAMP_OF_A_WEEK for example. Which one is more efficient? talking millions of records, and thousands of request in a minute.
NO, I would keep them in a single table since then I would need to fire only one UPDATE statement but if you separate them to 2 tables then either you will need to execute 2 update statement (or) create a AFTER UPDATE TRIGGER to insert into the other table (or) probably do a update join to update all the respective values ion both tables which to me looks more performance hit than having all the columns in single table.

Update one MySQL table with values from another

I'm trying to update one MySQL table based on information from another.
My original table looks like:
id | value
------------
1 | hello
2 | fortune
3 | my
4 | old
5 | friend
And the tobeupdated table looks like:
uniqueid | id | value
---------------------
1 | | something
2 | | anything
3 | | old
4 | | friend
5 | | fortune
I want to update id in tobeupdated with the id from original based on value (strings stored in VARCHAR(32) field).
The updated table will hopefully look like:
uniqueid | id | value
---------------------
1 | | something
2 | | anything
3 | 4 | old
4 | 5 | friend
5 | 2 | fortune
I have a query that works, but it's very slow:
UPDATE tobeupdated, original
SET tobeupdated.id = original.id
WHERE tobeupdated.value = original.value
This maxes out my CPU and eventually leads to a timeout with only a fraction of the updates performed (there are several thousand values to match). I know matching by value will be slow, but this is the only data I have to match them together.
Is there a better way to update values like this? I could create a third table for the merged results, if that would be faster?
I tried MySQL - How can I update a table with values from another table?, but it didn't really help. Any ideas?
UPDATE tobeupdated
INNER JOIN original ON (tobeupdated.value = original.value)
SET tobeupdated.id = original.id
That should do it, and really its doing exactly what yours is. However, I prefer 'JOIN' syntax for joins rather than multiple 'WHERE' conditions, I think its easier to read
As for running slow, how large are the tables? You should have indexes on tobeupdated.value and original.value
EDIT:
we can also simplify the query
UPDATE tobeupdated
INNER JOIN original USING (value)
SET tobeupdated.id = original.id
USING is shorthand when both tables of a join have an identical named key such as id. ie an equi-join - http://en.wikipedia.org/wiki/Join_(SQL)#Equi-join
It depends what is a use of those tables, but you might consider putting trigger on original table on insert and update. When insert or update is done, update the second table based on only one item from the original table. It will be quicker.