I'm trying to select Ids from a table if they were found by a query on another table (my final goal is to delete, from second table, rows with ids in the first query). Here are my attempts:
SELECT #MyList:=GROUP_CONCAT(Id SEPARATOR ', ') AS MyList
FROM myitems
WHERE MyString IS NULL OR MyString = '';
So #MyList contains '41, 42, 49, 51'
Query based on FIND_IN_SET returns only one row
SELECT Id
FROM myitems2
WHERE FIND_IN_SET(Id, #MyList) > 0;
Expected Result:
41
42
Returns
41
I get the same result if I use IN:
SELECT Id
FROM myitems2
WHERE Id IN (#MyList);
I also tryed a query based on LOCATE, but it returns Ids not in the set:
SELECT Id
FROM myitems2
WHERE LOCATE(Id, #MyList) > 0;
Expected Result:
41
42
Returns
1
2
4
5
9
41
42
How can I fix my queries?
FIND_IN_SET doesn't works because you have spaces after commas.
Replace :
GROUP_CONCAT(Id SEPARATOR ', ')
By :
GROUP_CONCAT(Id SEPARATOR ',')
Or you can do :
SELECT Id
FROM myitems2
WHERE FIND_IN_SET(Id, replace(#MyList, ' ', ''));
Related
I have this records:
Number
1, 2
1, 24
How to select only 2 by LIKE not 2 and 24
SELECT * FROM test WHERE number LIKE '%2%'
1, 2 // need only this record
1, 24
You should avoiding storing unnormalized CSV data like this. That being said, if you must proceed, here is one way:
SELECT *
FROM test
WHERE CONCAT(' ', number, ' ') LIKE '% 2 %';
find_in_set almost does what you want, but you'll have to remove the spaces in order to use it:
SELECT *
FROM test
WHERE FIND_IN_SET('2', REPLACE(number, ' ', '')) > 0
You can do it as follows :
SELECT `number`
FROM `test`
WHERE TRIM(SUBSTRING_INDEX(`number`, ',', -1)) = 2 or TRIM(SUBSTRING_INDEX(`number`, ',', 1)) = 2;
SUBSTRING_INDEX to split number, and TRIM to remove any space, then we search in to parts of the number.
I'd like to have the 3 most occuring strings from 2 rows of my database. The thing is the string may occur in column1 or column2. I'd like to use only one query. Thanks in advance
Sample DB:
id string1 string2
1 foo bar
2 bar foo
3 api foo
Output should then be:
string count
foo 3
bar 2
api 1
You can execute the following query:
SELECT string, COUNT(*) FROM
(
SELECT string1 string FROM mytable
UNION ALL
SELECT string2 string FROM mytable
) sub
GROUP BY string
ORDER BY COUNT(*) DESC
LIMIT 3
where mytable is your table name.
With this query:
You take the union of all strings, either string1 or string2.
You group these string by their count.
You order them by the biggest count to the lowest.
You take only the three firsts.
Hey guys i have did some coding in mysql to add a new line value to a row..
SELECT
babe
FROM
(SELECT
concat_ws(' ', 'assword \n') AS babe,
) test;
When i did like this i get an output like
BABE
assword name
What i need is an output like
BABE
assword
name(this would be below assword)
Is there any mysql functions to do this ??...or can i UPDATE the row ??..
I am a newbie in mysql. Hope you guys can help me out..Thanks in advance..
The statement includes a newline character in the babe column. You can confirm this by using the HEX() function to view the character encodings.
For example:
SELECT HEX(t.babe)
FROM ( SELECT CONCAT_WS(' ', 'assword \n') AS babe ) t
On my system, that Will output:
617373776F7264200A
It's easy enough to understand what was returned
a s s w o r d \n
61 73 73 77 6F 72 64 20 0A
(In the original query, there's an extraneous comma that will prevent the statement from running. Perhaps there was another expression in the SELECT list of the inline view, and that was returning the 'name' value that's shown in the example output. But we don't see any reference to that in the outer query.
It's not clear why you need the newline character. If you want to return:
BABE
-----------
asssword
name
That looks like two separate rows to me. But it's valid (but peculiar) to do this:
SELECT t.babe
FROM ( SELECT CONCAT_WS(' ', 'assword \nname') AS babe ) t
FOLLOWUP
Q: i just wanted to know how to add a new row below the assword ..if u know please edit the answer
It's not clear what result you are trying to achieve. The specification, divorced from the context of a use-case, is just bizarre.
A: If I had a need to return two rows: one row with the literal 'assword' and another row "below" it with the literal 'name', I could do this:
( SELECT 'assword' AS some_string )
UNION ALL
( SELECT 'name' AS some_string )
ORDER BY some_string
In this particular case, we can get the ordering we need by a simple reference to the column in the ORDER BY clause.
In the more general case, when there isn't a convenient expression for the ORDER BY clause, I would add an additional column, and perform a SELECT on the resultset from the UNION ALL operation. In this example, that "extra" column is named seq:
SELECT t.some_string
FROM ( SELECT 'assword' AS some_string, 1 AS seq
UNION ALL SELECT 'name', 2
)
ORDER BY t.seq
As another example:
( SELECT 'do' AS tone, 1 AS seq )
UNION ALL ( SELECT 're', 2 )
UNION ALL ( SELECT 'mi', 3 )
UNION ALL ( SELECT 'fa', 4 )
ORDER BY seq
I'd only need to add an outer SELECT if I needed a projection operation (for example, to remove the seq column from the returned resultset.
SELECT t.tone
FROM ( SELECT 'do' AS tone, 1 AS seq
UNION ALL SELECT 're', 2
UNION ALL SELECT 'mi', 3
UNION ALL SELECT 'fa', 4
)
ORDER BY t.seq
Assume my table column contains the following 2 string rows:
1, 5, 2, 31, 12, 1212, 111
21, 25, 32, 43, 112, 212, 311
I need a query to select a row that contains number 1 and contains number 2
My Query is:
SELECT *
FROM MyTable
WHERE My_String LIKE '%1%' AND My_String LIKE '%2%'
now this returns both of the rows when i want it to return only the first row.
It selects second row because numbers 21, 25, 32, 112, 212, 311 also contain number 1 and 2.
My question is how do i select all those rows where numbers 1 and 2 are contained in a string but not in 2-3 digit numbers. I want it to match strictly to those 1 and 2
http://www.sqlfiddle.com/#!2/b082d/5
select * from testtable
where instr(concat(', ', longstring, ', '), ', 2,') >0;
select * from testtable
where instr(concat(', ', longstring, ', '), ', 1,') >0
and instr(concat(', ', longstring, ', '), ', 2,') >0;
You can use a regular expression. [[:<:]] is a beginning word boundary and [[:>:]] is end word boundary.
SELECT * FROM MyTable
WHERE My_String RLIKE '[[:<:]]1[[:>:]]'
AND My_String RLIKE '[[:<:]]2[[:>:]]'
You have few options:
1- As mentioned in a comment on the main post, change the structure and don't store concatenated strings
2- write a function that splits the string and checks if the numbers 1 and 2 appear in the tokens after splitting.
3- write "where" clause that captures every possibility of appearance for a string:
a string can appear in the beginning, middle, end of the list or be the only element in the list. the last one, is not important since you require 1 and 2 to appear in a row, and therefore a list String containing a single element should be eliminated. so:
select *
from MyTable
where (My_String like '1,%' or My_String like '%, 1,%' or My_String like '%, 1')
and (My_String like '2,%' or My_String like '%, 2,%' or My_String like '%, 2')
I have a table containing countries:
id country
------------
0 Monaco
1 Mongolia
2 Montenegro
3 Morocco
4 Mozambique
5 Myanmar
I have a sub query that looks like this.
(SELECT country FROM COUNTRIES WHERE id < 10) AS ´Trip´
I want to have that subquery to be formatted as a string like this:
'Monaco, Mongolia, Montenegro, Morocco, Mozambique, Myanmar'
Is that possible?
You can use the group_concat function:
SELECT group_concat(country, ', ') FROM countries WHERE id < 10
What Lukas said, but use the SEPARATOR for your ,'s
SELECT group_concat(country SEPARATOR ', ') FROM countries WHERE id < 10
This is useful if you want a ';' instead of a ','