I have some data stored in table as comma separated string in user_values column, so as per my requirement I want to get specific user data and values stored in user_values column should get in single quote for this purpose I am using below query and it is working fine, but if specific user doesn't have any value in user_values column then below query getting user_values with one double quote inserted however it should get empty value for that column , so how to prevent double quote if column is empty for specific user.
table
id user_values
1 1,2
2 3,4,5
3 // empty / no value for this user
4 4,7
mysql query:
case 1: if user 1 have values in user_values column then
SELECT id,GROUP_CONCAT( CONCAT("'", REPLACE(user_values,",", "','") , "'")) as user_val
FROM user
WHERE id=1;
output:
case 2: if user don't have any value then inserting double in empty column
SELECT id, GROUP_CONCAT( CONCAT("'", REPLACE(user_values,",", "','") , "'")) as user_val
FROM user
WHERE id=3;
output:
I agree with GMB's diagnosis of the issue. However, I think that NULLIF() provides a simpler solution:
SELECT id,
GROUP_CONCAT( NULLIF(CONCAT("'", REPLACE(user_values, ",", "','") , "'"), "''"
) as user_val
FROM user
WHERE id = 3 ;
I suspect the some values of user_values are empty strings (which are different than null values, that group_concat() ignores). You can work around this with a case expression within group_concat() that turns empty strings to null values, like:
SELECT
id,
GROUP_CONCAT(CASE
WHEN user_values = '' THEN NULL
ELSE CONCAT("'", REPLACE(user_values,",", "','"), "'")
END) as user_val
FROM user
WHERE id = 3;
Related
I have a varchar(255) field within a source table and the following contents:
50339 My great example
2020002 Next ID but different title
202020 Here we go
Now I am processing the data and do an insert select query on it. From this field I would need the INT number at the beginning of the field. IT IS followed by 2 spaces and a text with var length, this text is what I need as well but for another field. In General I want to to put text and ID in two fields which are now in one.
I tried to grab it like this:
SELECT STATUS REGEXP '^(/d{6,8}) ' FROM products_test WHERE STATUS is not null
But then I learned that in MySQL 5.x there are no regexp within the SELECT statement.
How could I seperate those values within a single select statment, so I can use it in my INSERT SELECT?
From the correct solution of user slaakso, resulted another related problem since somtimes the STATUS field is empty which then results in only one insert, but in case there is a value I split it into two fields. So the count does not match.
My case statement with his solution somehow contains a syntax problem:
CASE STATUS WHEN ''
THEN(
NULL,
NULL
)
ELSE(
cast(STATUS as unsigned),
substring(STATUS, locate(' ', STATUS)+3)
)
END
You can do following. Note that you need to treat the columns separately:
select
if(ifnull(status, '')!='', cast(status as unsigned), null),
if(ifnull(status, '')!='', substring(status, locate(' ', status)+2), null)
from products_test;
See db-fiddle
I have a table which contains two fields. The first is name of type string. The second contains one or more strings separated by comma (but it can contain a single string with no commas at all)
I want to construct a query to know if the string in the name field does not exist in every comma separated strings in the names field.
Example 1:
---------------------------------------------------------
name names
---------------------------------------------------------
myname xmyname,myname,mynamey
All the comma separated strings contain the word myname. So the query shoudl not return this row.
But, Example 2:
---------------------------------------------------------
name names
---------------------------------------------------------
myname x,myname,mynamey
Should be returned. Because x does not contain myname.
The condition is that, if the string in the field name does not exists in each of the comma separated strings in the names field, then return the row.
This is not correct as this query will not return true in example 2 (which contains x which does not contain myname).
IMPORTANT NOTE:
1) There is not limit of how many commas there. It can be 0 commas or more. How to deal with this?
2) The strings are variables. It is not always the case that the string is myname. Each row contains a different string in the name field.
Try this regular expression:
where not concat(names, ',') regexp replace('^([^,]*{n}[^,]*,)*$', '{n}', name)
db-fiddle demo
How to read the pattern:
The inner pattern [^,]*{n}[^,]*, means
Any non comma character [^,] repeated any number of times (* means no times or multiple times).
followed by the value of the column name ({n} is a placeholder and will be replaced with the actual value using the replace() function)
followed by any non comma character [^,] repeated any number of times
followed by a comma
The outer pattern ^({inner_pattern})*$ means
Start of the string (^)
followed by the inner pattern repeated any number of times
followed by end of string ($)
To make this work, a comma is appended to the names column (concat(names, ',')), so that every element in the string ends with a comma.
The pattern will ensure, that any element in the comma separated string contains the value of the name column. Since you want the opposite result, we use where not ...
Assuming "myname" does not appear twice between two commas, you can count the commas and "myname"s:
where (length(names) - length(replace(names, ','))) >=
length(names) - length(replace(names, 'myname', '12345'))
This answer started off giving an incorrect REGEXP solution. But the best thing to do here would be to fix your data model, such that each name in the names column is actually on a separate row:
name | names
myname | xmyname
myname | myname
myname | mynamey
somename | x
somename | myname
somename | mynamey
Now we can do a simple aggregation query to answer your question:
SELECT name
FROM yourTable
GROUP BY name
HAVING COUNT(CASE WHEN names NOT LIKE CONCAT('%', name, '%') THEN 1 END) > 0;
Demo
You can approach this using the following SQL query
SELECT
name, names
FROM
`tablename`
WHERE
(LENGTH(names) - LENGTH(REPLACE(names, ',', '')) + 1)
=
ROUND (
(
LENGTH(names)
- LENGTH( REPLACE ( names, name, "") )
)/ LENGTH(name)
);
Explanation:-
This Will give you how many words are separated with ,
(LENGTH(names) - LENGTH(REPLACE(names, ',', '')) + 1) -
Following is matching the name in each row and returning how many times it found
ROUND (
(
LENGTH(names)
- LENGTH( REPLACE ( names, name, "") )
) / LENGTH(name)
)
DEMO
I would like to ask how to split string from column (all rows in table) by " " and insert result separated by , into another column in same table?
Many thanks for any advice.
Table struct example:
------------------------------------------
| Original string | Spliced string |
------------------------------------------
| Some string 001 | Some,String,001 |
------------------------------------------
If I needed to "split" a string on a delimiter, I'd likely make use of the nifty SUBSTRING_INDEX function. But there are a few quirks to be aware of.
The approach I would take would certainly be to write a SELECT statement first. That would include the expression(s) in the SELECT list that return the "separated" values that I wanted to assign to another column. I'd get those expressions tested using a SELECT statement, before I wrote an UPDATE statement.
SELECT t.id
, t.column_i_want_to_split
, expr1
FROM mytable t
ORDER BY t.id
To test specific cases, I'd make use of an inline view
SELECT t.id
, t.note
, t.val
, expr1
FROM ( SELECT 1 AS id, 'empty string test' AS note, '' AS val
UNION ALL SELECT 2, 'null', NULL
UNION ALL SELECT 3, 'one space', ' '
UNION ALL SELECT 4, 'four spaces', ' '
UNION ALL SELECT 5, 'test5', ' abc def '
UNION ALL SELECT 6, 'test6', 'g hi kl m'
) t
ORDER BY t.id
Once I had the expression(s) returning the values I want to assign to another column, I'd convert the SELECT into an UPDATE statement. To process all rows, omit the WHERE clause.
UPDATE mytable t
SET t.another_column = expr1
Without a more definitive specification, or at least some concrete examples of what you are attempting to achieve, we're just guessing. Given only a general description of the problem, all we can offer is some general advice.
SELECT username FROM `info` WHERE id
in ('919953990950_1403180247868.707,
919953990950_1403239797121.525,
919953990950_1403241821083.838,
919953990950_1403248486971.661,
919953990950_1403248511255.484,
919953990950_1403248860947.79,
919953990950_1403255594277.013') and username !='1403176452487620892' limit 50
this is not selecting rows what's wrong in my query?
You need to enclose each value in single quotes, not the entire list:
SELECT username
FROM `info`
WHERE id in ('919953990950_1403180247868.707',
'919953990950_1403239797121.525',
'919953990950_1403241821083.838',
'919953990950_1403248486971.661',
'919953990950_1403248511255.484',
'919953990950_1403248860947.79',
'919953990950_1403255594277.013'
) and
username <> '1403176452487620892'
limit 50;
Try this by putting every value in quotes '' else it would consider the entire as one string and also replace != with <>:
SELECT username
FROM `info`
WHERE id
in ('919953990950_1403180247868.707',
'919953990950_1403239797121.525',
'919953990950_1403241821083.838',
'919953990950_1403248486971.661',
'919953990950_1403248511255.484',
'919953990950_1403248860947.79',
'919953990950_1403255594277.013') and username <>'1403176452487620892'
OP's comment:
i am inserting it by scala language thats a string
Use find_in_set when set of values are in the form of a comma separated values
SELECT username FROM `info`
WHERE FIND_IN_SET( id, csv_values )
AND username !='1403176452487620892' limit 50;
In the above example replace 'csv_values' with the string of values received from SCALA
I suggest you to go with Prepared Statement to bind values.
Refer to:
FIND_IN_SET( str, strlist )
Return the index position of the first argument within the second
argument
I need to count the non-empty (by which I mean a string containing at least 1 character) rows grouped by a particular ID. Eg. my data might look like this:
form_id mapping
1 'value_1'
1 ''
1 'value_2'
2 ''
2 NULL
3 'value_3'
and I want to count the non-empty values for each form, so I want the results to look like this:
form_id mapping_count
1 2
2 0
3 1
If the empty values were all NULL, I guess I could use
SELECT form_id, count(mapping) FROM table GROUP BY form_id
...but that would include zero-length strings in the count, which I don't want.
I could use a where clause to only return rows where a value exists in the mapping column, but I want to return the form IDs that have no mappings, so that is no good either.
I'm guessing I need a subquery of some sort, but am having trouble putting it together.
SELECT form_id, COUNT(NULLIF(TRIM(mapping), ''))
FROM mytable
GROUP BY
form_id
This will not count records that don't contains at least one non-whitespace character (this includes whitespace strings, empty strings and NULLs).
If a non-empty all-whitespace string is valid, use this:
SELECT form_id, COUNT(NULLIF(mapping, ''))
FROM mytable
GROUP BY
form_id