MySQL move comma separated values from one column into another - mysql

Good Evening Everyone;
I have a table in MySql that I would like to update as follows. Just as an FYI I have searched this topic and have yet to find a solution.
The table name is ALK_Results_NEW in a MySQl database, the data in the ICD9 column contains data seperated by commas.
I need to keep the first set in the ICD9 column so for example the first row has V57.9 , 246.9.
I need to keep the V57.9 in the ICD9 column and move 246.9 into the ICD9_SECONDARY column.
If a row has more than 2 then I need to move all other into the ICD9_OTHER column (This column can have mulitple ICD9 Codes separated by commas)
To summarize the first code needs to stay in the ICD9 column and the second set of codes needs to be moved into the ICD9_SECONDARY. After the data is moved the ICD9 Column should only have the forst set of codes.
Any help would be greatly appreciated.

Assuming the two columns already exist in the table, you can change the data using an update:
update alk_results_new
set icd9_secondary = substr(icd9, instr(icd9, ',') + 1),
icd9 = substring_index(icd9, ',', 1)
where icd9 like '%,%';
EDIT:
Oops, I didn't realize there were three columns. The approach is similar, but a little more complicated because you need to take into account the length of the strings. I think the following should do what you want:
update alk_results_new
set icd9_other = (case when icd9 like '%,%,%'
then substr(icd9, length(substring_index(icd9, ',', 2)) + 2)
end),
icd9_secondary = (case when icd9 like '%,%'
then substring_index(substring_index(icd9, ',', 2), ',', -1)
end),
icd9 = substring_index(icd9, ',', 1);
Note: test the logic out on a select before running the update.

Related

Counting how many fields (in a row) are filled in SQL

I want to count how many columns in a row are not NULL.
The table is quite big (more than 100 columns), therefore I would like to not do it manually or using php (since I dont use php) using this approach Counting how many MySQL fields in a row are filled (or empty).
Is there a simple query I can use in a select like SELECT COUNT(NOT ISNULL(*)) FROM big_table;
Thanks in advance...
Agree with comments above:
There is something wrong in the data since there is a need for such analysis.
You can't completely make it automatic.
But I have a recipe for you for simplifying the process. There are only 2 steps needed to achieve your aim.
Step 0. In the step1 you'll need to get the name of your table schema. Normally, the devs know in what schema does the table reside, but still... Here is how you can find it
select *
from information_schema.tables
where table_name = 'test_table';
Step 1. First of all you need to get the list of columns. Getting just the list of cols won't help you out at all, but this list is all we need to be able to create SELECT statement, right? So, let's make database to prepare select statement for us
select concat('select (length(concat(',
group_concat(concat('ifnull(', column_name, ', ''###'')') separator ','),
')) - length(replace(concat(',
group_concat(concat('ifnull(', column_name, ', ''###'')') separator ','),
'), ''###'', ''''))) / length(''###'')
from test_table')
from information_schema.columns
where table_schema = 'test'
and table_name = 'test_table'
order by table_name,ordinal_position;
Step 3. Execute statement you've got on step 2.
select (length(concat(.. list of cols ..)) -
length(replace(concat(.. list of cols .. ), '###', ''))) / length('###')
from test_table
The select looks tricky but it's simple: first replace all nulls with some symbols that you're sure you'll never get in those columns. I usually do that replacing nulls with "###". that what all that "ifnull"s are here for.
Next, count symbols with "length". In my case it was 14
After that, replace all "###" with blanks and count length again. It's 11 now. For that I was using "length(replace" functions together
Last, just divide (14 - 11) by a length of a replacement string ("###" - 3). You'll get 1. This is exactly amount of nulls in my test string.
Here's a test case you can play with
Do not hesitate to ask if needed

MySQL Query for Similar Column Value

In my database table, Due to some mistake same row has been entered twice, But it is now having one column value with some appended numeric value in the duplicate entry.
For example,
If my table has a column named filename, Then in one row it has value 'some-random-name.pdf'.
And in the duplicate row, it has value 'some-random-name-1532.pdf'.
I need to identify all such records. Please note that there can be any or zero number of dash(-) in the filename. So Like query something like '%-____-%.pdf did not help me.
Assuming that complete filename contains only one dot between name and extension you may try this:
WHERE SUBSTRING_INDEX(t1.value, '.', -1) = SUBSTRING_INDEX(t2.value, '.', -1)
AND LOCATE(SUBSTRING_INDEX(t1.value, '.', 1), SUBSTRING_INDEX(t2.value, '.', 1)) = 1

MySQL move part of a cell to another column

I have the following imported to TableA, Column 'Clothes' and Column 'Colours'
The problem is the import has put in the 'Clothes' column 'Jeans - Blue' and 'Jumper - Red' etc etc
Please could someone help me with a query to keep everything before the - in 'Clothes' and everything after the - into 'Colours' and removing the - altogether.
Two steps for this.
First, update the colors:
UPDATE yourTableA T
SET T.Colours = TRIM(SUBSTR(T.Clothes,INSTR(T.Clothes,'-') + 2));
Second, update the Clothes:
UPDATE yourTableA T
SET T.Clothes = TRIM(SUBSTR(T.Clothes,1,INSTR(T.clothes,'-')-1));
I've used SUBSTR as my string swiss army knife here, and INSTR to locate the position of the - in between. You can do without TRIM, but I usually use this in those cases to avoid unnecessary white spaces.
There surely are more direct ways to do it, but this'll work.
The SUBSTRING_INDEX function is convenient, and the TRIM function can remove leading and trailing spaces. For example:
SELECT TRIM(SUBSTRING_INDEX(a.Clothes,'-',1)) AS Clothes
, TRIM(SUBSTRING_INDEX(a.Clothes,'-',-1)) AS Colours
FROM TableA a
WHERE LENGTH(a.Clothes)-LENGTH(REPLACE(a.Clothes,'-','')) = 1
(NOTE: the query above is returning the substring before the first '-' character, and is returning the substring after the last '-' character. So any values with more than one dash would lose the portion between the first and last dashes, consider e.g. 'A - B - C - D', the query above returns the A and returns the D, and loses everything else.
To handle this anomaly, the WHERE clause checks that the string contains a single occurrence of the '-' character.
Once you have a query you are happy with, you can turn that into an UPDATE statement, BUT be VERY careful about the order you assign new values to columns. Unlike other relational databases, MySQL does not guarantee that a reference to an existing column within the statement will be the value of the column from the beginning of the statement... the only guarantee is that it will be the value that is currently assigned. So, the order that the columns is assigned is important!
UPDATE TableA a
SET Colours = TRIM(SUBSTRING_INDEX(a.Clothes,'-',-1))
, Clothes = TRIM(SUBSTRING_INDEX(a.Clothes,'-',1))
WHERE LENGTH(a.Clothes)-LENGTH(REPLACE(a.Clothes,'-','')) = 1
Note that if we were to assign the Clothes column before we assigned a value to the Colours column, the value we want assigned to Colours would be "lost".
You can do it in a single UPDATE as follows:
UPDATE TableA
SET `Colours` = SUBSTRING_INDEX(`Clothes`, ' - ', -1),
`Clothes` = SUBSTRING_INDEX(`Clothes`, ' - ', 1)
;
You can experiment with SQL Fiddle Demo I created from your data.
Here's the data I worked with:
CREATE TABLE TableA
(Clothes varchar(20), Colours varchar(20))
;
INSERT INTO TableA
(`Clothes`, `Colours`)
VALUES
('Jeans - Blue', NULL),
('Jumper - Red', NULL)
;
This the result of SELECT * FROM TableA; :
CLOTHES COLOURS
Jeans Blue
Jumper Red

MySQL - Search CSV in CSV Column

I have a table with a column that has CSV.
TableA:
field_id | matches
---------------------
1 1,2,4,6,8,11,14,56
Now I need to get the field_id that matches a user given csv. So for instance, user string is 1,4,11, then it should return some value may be just true.
1.) Find_in_set does not work. Because it takes only one element and searches that in a SET/CSV column.
2.) Cannot use like concat('%,', user_input , ',%'). Because user input may not be in order.
Any other ideas? I guess this is a very common scenario.
Note: I dont need to search all records. I need to search a specific record. So in the above table, I just need to search one record that has field_id = 1. i.e. (where field_id = 1). (May not matter, but just an info)
Well, this is a good argument for having data in a proper relational form. But, you can try:
select t.*
from t
where (find_in_set($user_input, 1) = 0 or
find_in_set(substring_index(substring_index($user_input, ',', find_in_set($user_input, 1)), ',', -1), matches) > 0) and
(find_in_set($user_input, 2) = 0 or
find_in_set(substring_index(substring_index($user_input, ',', find_in_set($user_input, 2)), ',', -1), matches) > 0) and
. . .
Do this for however many values you might have in the userinput set.
I presume there is no straight solution with MySQL query like Find_In_Set. So I guess I will have to handle this with multiple queries or with Looping.

Delete specific word from table column in MySQL?

I have ONE column in MySQl table which contains words in this format:
Name - Name2 - Name3
and I'd like to delete Name2, and to leave just Name - Name3
So I just need to delete middle word, and not the entire column! The middle word is always the same.
Is that possible?
update your_table
set your_column = concat(SUBSTRING_INDEX(your_column, '-', 1), '-',
SUBSTRING_INDEX(your_column, '-', -1))
SQLFiddle example
substring-index doc
The easiest way is to use REPLACE.
UPDATE table SET column=REPLACE(column,'Yourstring','')
Suppose I have a table name car, and inside this table, there is a column called version. In this version, there are few data which has the string 'Auto', and I want to remove this.
GT 1.4 Turbo MultiAir 2d Auto -> GT 1.4 Turbo MultiAir 2d
So, the simple solution will be:
UPDATE cars SET version=REPLACE(version,'Auto','')
It will work for every occurrence.