SQL query update column value twice in single query (MySQL) - mysql

I have a text column named data which has value in format
"`set1:val1,val2|set2:val3`"
so I have 2 sets field and n number of value fields in each set. I know this isn't normalized or proper approach to store data but it's a legacy project I can't change the schema now.
Now I need a single query given two values for each sets say val4 and val5 I need my final data field to be
"`set1:val1,val2,val4|set2:val3,val5`"
I'm really not an expert in SQL query so need an update query for above. Note that I will always get only two values for each set and need to append in existing set values.

This is an ugly solution to an ugly problem
UPDATE table
SET data = CONCAT(REPLACE(data,'|',',val4|'), ',val5')
WHERE data = '...'
The REPLACE operation changes set1:val1,val2|set2:val3 to set1:val1,val2,val4|set2:val3, and then the CONACT operation changes that to set1:val1,val2,val4|set2:val3,val5

Related

SQL how to do string replace for any SQL query data which comes out of column without using SQL

I have a table with a column for different fruit names - Apple, Orange, Banana etc. These fruit names can have duplicates.
Right now if I do a SQL Select, I get the names as it is. I want to change the data so that every "Apple" gets replaced with "Sweet Apple" and every "Orange" gets replaced with "Mandarin".
I know I can use the replace function in my SQL queries. However I don't want to/can't modify my SQL queries. I was trying to leave changing the SQL as a last resort because that needs to be done on several different nodejs scripts.
I am wondering if there is some way in the database itself which can make it return these altered data automatically. Sort of like a filter / pipeline / constraint (I am not sure what to call it) which is set on a specific column of a table and makes it automatically do this replace function for any data which is queried from this table.
I would like an answer for mainly Postgres and MySQL and if possible for SQL Server too.
No, the closest would be triggers on Insert and Update to replace the data as it comes in, but you cannot override data that is being queried without specifying it in the query. You can create a view that would show the replaced strings.
It has its drawbacks, but you could do this:
Change the name of the Fruit column to something else, and then create a new Computed column that does the REPLACE you want on the newly-renamed Fruit column, and give this new column the name of the old column, so that all your existing queries will hit the new column.
Drawback is that any existing INSERT/UPDATE queries have to be changed to INSERT/UPDATE to the new name of the old column.
Well, The Idea of a database is "storing values". So, if you are querying these values, you only have little options on modification.
Your expectation of handling is clearly up to your programming language. Whenever you output a value retrieved from the database, wrap it, filter it - return whatever you need instead of the stored value, i.e.:
public static string filter(value){
if (value == "Apple")
return "Sweet Apple";
if (value == "Orange")
return "Mandarine";
return value;
}

How to Guess schema in Mysqlinput on the fly in Talend

I've build a job that copy data from a mysql db table to b mysql table.
The table columns are the same except sometimes a new column can be added in table a db.
i want to retrieve all the columns from a to b but only those that exists in table b. i was able to put in the query specific select colume statment that exists in table b like:
select coulmn1,column2,columns3... from table a
the issue is if i add a new column in b that matches a the talend job schema in Mysqlinput should be changed as well cause i work with build in type.
Is there a way to force the schema columns during the job running?
If you are using a subscription version of Talend, you can use the dynamic column type. You can define a single column for your input of type "Dynamic" and map it to a column of the same type in your output component. This will dynamically get columns from table a and map them to the same columns in table b. Here's an example.
If you are using Talend Open Studio, things get a little trickier as Talend expects a list of columns for the input and output components that need to be defined at design time.
Here's a solution I put together to work around this limitation.
The idea is to list all table a's columns that are present in table b. Then convert it to a comma separated list of columns, in my example id,Theme,name and store it in a global variable COLUMN_LIST. A second output of the tMap builds the same list of columns, but this time putting single quotes between columns (so as they can be used as parameters to the CONCAT function later), then add single quotes to the beginning and end, like so: "'", id,"','",Theme,"','",name,"'" and store it in a global variable CONCAT_LIST.
On the next subjob, I query table a using the CONCAT function, giving it the list of columns to be concatenated CONCAT_LIST, thus retrieving each record in a single column like so 'value1', 'value2',..etc
Then at last I execute an INSERT query against table b, by specifying the list of columns given by the global variable COLUMN_LIST, and the values to be inserted as a single string resulting from the CONCAT function (row6.values).
This solution is generic, if you replace your table names by context variables, you can use it to copy data from any MySQL table to another table.

How to store the result of a SQL statement as a variable and use the result in an SSIS Expression?

I am using a SSIS Data Flow Task to transfer data from one table to another. Column A in Table A contains a number, the last 3 digits of which I want to store in Column B of Table B.
First I'm trying to grab all of the data in Column A and store in a variable via a simple SELECT statement SELECT COLUMN_A FROM TABLE_A. However, the variable stores the statement as a string when I want the result set of the query. I have set the EvaluateAsExpression property to False but to no avail.
Secondly I want to be able to use the result of this query in the Derived Column of my Data Flow to extract the last 3 digits and store the values in Column_B in the destination. The expression I have is:
(DT_STR,3,1252)RIGHT(#User::[VariableName],3)
I want to store this as a string hence the (DT_STR,3,1252) data type.
All I'm getting so far in Column_B of Table_B is is the last 3 characters of the SELECT statement "E_A". There is a lot of useful information on the web including YouTube videos for things like setting file paths and server names as parameters or variables but I can't see many relevant to the specifics of my query.
I have used an Execute SQL Task to insert row counts from flat files but, in this example, I want to use the Derived Column tool instead.
What am i doing wrong? Any help is gratefully appreciated.
I prefer to do all the work in SQL if you aren't doing anything else with that number.
select right(cast(ColA as varchar(20)),3) from tableA
-- you can add another cast if you want it to be an int
use that in an execute sql to result set = single row.
Map that to a variable.
In a derived column in data flow you can set that variable to the new column.
Thanks KeithL thats one solution I will use in future but I found another.
I dropped the variable and in the Expression box of the Transformation Editor did:
(DT_STR,3,1252)RIGHT((DT_STR,3,1252)Column_A,3).
In my question, I failed to cast Column_A from Table_A as a string. The first use of (DT_STR,3,1252) simply sets the destination column as a string so as not to use the same data type as the source which in my case was int.
Its the 2nd use of (DT_STR,3,1252) that actually casts Column_A from int to a string.

Update Table Column off of Query Column

I am trying to Update a column in my table Inputcounts called concatenate off of a query called InputConcatenates that has a column also called concatenate. I am running an update query with the field name as concatenate the table name as InputCounts and the update to field as [InputConcatenates].[Concatenate]. But every time I run the query it pulls back that 0 records will be updated. Is my syntax wrong possibly?
Update Query SQL:
UPDATE InputCounts INNER JOIN InputConcatenate
ON InputCounts.CONCATENATE = InputConcatenate.CONCATENATE
SET InputCounts.CONCATENATE = [InputConcatenate].[CONCATENATE];
InputConcatenate Query SQL:
SELECT InputCounts.FLEET, InputCounts.AMMs, [FLEET] & [AMMs] AS CONCATENATE
FROM InputCounts;
You reported this query accomplishes what you want ...
UPDATE InputCounts
SET CONCATENATE = [FLEET] & [AMMs]
WHERE CONCATENATE Is Null;
That may be fine. However CONCATENATE is not updated until you execute the UPDATE, and does not get updated (after having previously received a value) in response to changes in FLEET or AMMs
Decide whether CONCATENATE really needs to exist as a field in your table. You could use a query to derive it whenever you need it:
SELECT *, FLEET] & [AMMs] AS CONCATENATE
FROM InputCounts;
With the query, CONCATENATE will always be up to date.
If your database is ACCDB format and your Access version is >= 2010, another possibility is to make CONCATENATE a "calculated field" type in the table's design:
If you prefer CONCATENATE be Null whenever FLEET or AMMs is Null, change the field's Expression property to [FLEET] + [AMMs]
The advantage of a calculated field is that Access automagically updates its value without further effort (like executing an UPDATE) from you.
A disadvantage is that you can't index a calculated field. That means it's not suited for joins, WHERE criteria, ORDER BY, etc. You'll have to decide whether it's a reasonable fit for your application. :-)

SQL Update with Variable as Parameter

I am working on a stored procedure in MySQL to update a row in a SQL table. What I have is a table where several of the columns are named incrementally. EX: Page_1, Page_2, Page_3....etc.
The data stored in these locations is updated at different times and I have another column to store the number of times the row has been updated. The count variable gets incremented each time the procedure runs and that allows me to utilize it's value in keeping track of where the next update of the data should take place.
From my research I keep finding solutions utilizing "Dynamic SQL." I do not understand how to utilize this to resolve my issue.
I want to pass a variable in to an update statement as the column name.
The code I currently have is as follows.
SET COUNT = COUNT + 1; -- modify count from count column
SET COLUMNLOCATIONVARIABLE = CONCAT('Page_' , COUNT); -- concatenate the count with the column "Prefix"
UPDATE Table
SET COLUMNLOCATIONVARIABLE = INPUTVARIABLE --Use the concatenated statement as the column name and update it with input data
WHERE mainID = INPUTID;
If anyone could explain to me how to pass this variable in as a column name using Dynamic SQL or another solution utilizing non-dynamic SQL I would appreciate it.
Thanks in advance.
This isn't the way to use a database. Create a new table for your Page_* columns, linked to the main table by an identity, with a page number column. Then you can update and include as many pages as you need, addressed by the main identity and the page number.