MYSQL - searching strings within a select - mysql

I want to be able to search a field in the database and see if the "changed from" and "to" values are different(the values are stored within a string in a single field).
Here is an example of what the string in the field looks like
Instance Person(34) modified by 1.
Field phone_number changed from "123" to "123".
Current field values are:
first_name => "alex"
last_name => "Handley"
In this example they are the same so would not be returned.
is it possible to do this ?
Alex

This is really a job for a regular expression, not a database query.
You could do it with a stored procedure which makes a query, chops up the result, and compares the two parts. But, again, this type of logic belongs at the application layer - either beforehand, storing the parts of the string you'll need to compare separately, or afterwards, extracting the useful info from the single database column.

MySQL has pretty nice regular expression support. (It's also fast; I've found that REGEXP is often faster than LIKE).
I don't believe that it has back reference support, so it would be difficult to compare in a single query. You might be able to do it with a clever join or a stored procedure.

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 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.

what is the best approach to find duplicates in my Db table

In my app the user can select multiple filter options. I store this in a DB table.
For example
User 1 can select filters A^B
User 2 can select filters AORC^D
and so forth.
The way it is stored in Db is
user filter_selected
user1 A^B
user2 AORC^D
Now the criteria is no user can have the same filters selected. So if user 3 comes and select A^B or B^A it should throw a error.
I am trying to come up with a smart logic to validate this in javascript.
One approach is go through all the users in the DB (can be many) and sort alphabetically and check if its the same. So in our example A^B and B^A will be the same AB^. This way I can check. Any other better approach may be using mysql command itself ?
you can sort your filter rule based on character and then insert it to do
for example, B^A will convert to AB^ and when you want to check you can sort your filter and then search it
if you want to have an original filter you don't care about the size of your database and more you care about speed you can save original as another column too.if you are care about size of database you can just save the original filter and when you want to search select the rows that have the same length as your filter and then you need to sort alphabetically or you can save index of every filter chars for example when you change A^B to AB^ you can save this filter AB^|021 but this will need to some more space too like original column and I don't suggest this method. also if your filters are always in small length you can don't fetch all record and compare to all. you can just create all possible way of the filter(for example AB^ A^B B^A BA^ ^AB ^BA) but you must be careful because in this method you are creating n! string and this is not good at all, just for too small length string its ok and that's when you have too many records in your database this method can be good

Creating a global variable in Talend to use as a filter in another component

I have job in Talend that is designed to bring together some data from different databases: one is a MySQL database and the other a MSSQL database.
What I want to do is match a selection of loan numbers from the MySQL database (about 82,000 loan numbers) to the corresponding information we have housed in the MSSQL database.
However, the tables in MSSQL to which I am joining the data from MySQL are much larger (~ 2 million rows), are quite wide, and thus cost much more time to query. Ideally I could perform an inner join between the two tables based on the loan number, but since they are in different databases this is not possible. The inner join that is performed inside a tMap occurs after the Lookup input has already returned its data set, which is quite large (especially since this particular MSSQL query will execute a user-defined function for each loan number).
Is there any way to create a global variable out of the output from the MySQL query (namely, the loan numbers selected by the MySQL query) and use that global variable as an IN clause in the MSSQL query?
This should be possible. I'm not working in MySQL but I have something roughly equivalent here that I think you should be able to adapt to your needs.
I've never actually answered a Stackoverflow question and while I was typing this the page started telling me I need at least 10 reputation to post more than 2 pictures/links here and I think I need 4 pics, so I'm just going to write it out in words here and post the whole thing complete with illustrations on my blog in case you need more info (quite likely, I should think!)
As you can see, I've got some data coming out of the table and getting filtered by tFilterRow_1 to only show the rows I'm interested in.
The next step is to limit it to just the field I want to use in the variable. I've used tMap_3 rather than a tFilterColumns because the field I'm using is a string and I wanted to be able to concatenate single quotes around it but if you're using an integer you might not need to do that. And of course if you have a lot of repetition you might also want to get a tUniqueRows in there as well to save a lot of unnecessary repetition
The next step is the one that does the magic. I've got a list like this:
'A1'
'A2'
'B1'
'B2'
etc, and I want to turn it into 'A1','A2','B1','B2' so I can slot it into my where clause. For this, I've used tAggregateRow_1, selecting "list" as the aggregate function to use.
Next up, we want to take this list and put it into a context variable (I've already created the context variable in the metadata - you know how to do that, right?). Use another tMap component, feeding into a tContextLoad widget. tContextLoad always has two columns in its schema, so map the output of the tAggregateRows to the "value" column and enter the name of the variable in the "key". In this example, my context variable is called MyList
Now your list is loaded as a text string and stored in the context variable ready for retrieval. So open up a new input and embed the variable in the sql code like this
"SELECT distinct MY_COLUMN
from MY_SECOND_TABLE where the_selected_row in ("+
context.MyList+")"
It should be as easy as that, and when I whipped it up it worked first time, but let me know if you have any trouble and I'll see what I can do.

MySQL wrong output with IN clause and parameter

I'm having a hard time with a query in MySQL.
I'm working with Delphi XE and I'm sending a query with some parameter to MySQL. Here's an example for the query:
SELECT * FROM users u WHERE u.id IN (:idUsers);
The ':idUsers' is the variable that will receive the parameter I send with Delphi, which is a string containing that is formatted like this, ex.: 1,2,3
The problem is that with this string, I receive only the first user (id = 1). From what I can see, its just like MySQL is adding some quote ('') at the beginning and at the end of the string I send, like if it was '1,2,3' instead of 1,2,3. I've tried this select :
SELECT * FROM users u WHERE u.id IN ('1,2,3');
and it does indeed return only the first user..
I had a function in MSSQL that was splitting the string I sended and returning a temporary table, but we recently switched to MySQL, and from what I read, MySQL doesn't allow returning a table.
Anyone has a clue on how to solve this problem? I've been scrapping the Web for an answer and haven't found one for this specific problem.
Thanks for the help.
Parameters don't work like that; they have no idea that what you're trying to provide is a comma-separated list of values. If you set ParamByName('WhatEver').AsString or Value, it thinks you mean a quoted string that contains everything that belongs in that parameter. So it's doing exactly what it appears to - it's passing IN ('1, 2, 3'), instead of the intended IN (1, 2, 3).
You'll need to either go back to parsing it out yourself and using a temp table, or build the WHERE clause dynamically and concatenating it before executing the query. (Actually, you could build the query dynamically, creating a new parameter for each of the items in the IN clause, and then loop through and assign values to each of those dynamically created parameters, but that gets very ugly very quickly.)
If you have a variable number of parameters in the IN clause, you could build a temporary table in MYSQL (which only contains a column called ID), load the parameter values into the temporary table and then do something like this:
SELECT * FROM users u WHERE u.id IN (SELECT ID FROM TEMPTABLE);
As long the TEMPTABLE only contains the values you want to query, the table space scan is acceptable.
You can then have a variable number of values. You could also make the table permanent, and store the parameters. Add a column for the User, and each user can store their individual parameters.