MySQL: Split string SQL to be used in WHERE clause - mysql

I am looking for a way to use the IN keyword in JasperReport. My query looks like:
SELECT * FROM table_name WHERE CID IN (145,45, 452);
following that in jasper report I can setup this;
SELECT * FROM table_name WHERE CID IN ($P{MY_CIDS});
and from my Java I would send $P{MY_CIDS} as a String, so my query will look like
SELECT * FROM table_name WHERE CID IN ("145,45, 452");
My questions is how to transform in SQL "145,45, 452" to a valid query so it would take into consideration each value separately 145, 45, 452
All help is appreciated.

WHERE FIND_IN_SET(CID, "145,45,452")
But this query will always cause table fullscan. So I suggest you to rewrite your code and use proper IN (A, B, C) syntax.

You've two options. The more common, is to rewrite your query like this instead:
SELECT * FROM table_name WHERE CID IN (?, ?, ?, ..., ?);
I'm not sure the other is valid for MySQL, but it works fine in PostgreSQL. It is to use an immutable function that parses the string into a set of integers, and instead use:
SELECT * FROM table_name WHERE CID IN (split_to_int(?));

SELECT * FROM table_name WHERE CID IN ($P!{MY_CIDS});
Just use
$P!{MY_CIDS}
(exclamation mark between $P and {MY_CIDS}).
Jasper will now concatinate the Strings like this:
"SELECT * FROM table_name WHERE CID IN ("
+"145,45,452"
+")";
resulting in:
SELECT * FROM table_name WHERE CID IN (145,45,452);
Took me a long time to get that but now it works for me."

Related

MySQL When to use quotation after SELECT AS

After reviewing the use of SELECT in mysql, I found after as, sometimes without single quotation and sometimes has.
For example:
SELECT * AS DAY
compare to:
SELECT * AS 'Cancellation Rate'
So when to use single quotation after SELECT AS?
for composite name eg: Cancellation Rate.. use backtics not quotes
select my_col_name as `Cancellation Rate`
from my_table
The proper syntax would be something like:
SELECT column_name AS colname FROM table_name
As mentioned in the comment, you cannot not alias a 'select all', which is what * represents. It selects ALL columns from your table.
You can also alias a table's name, like:
SELECT * FROM employees e WHERE column_name = 1;
When you alias a table's name, it can be easier to read in larger and more complex queries such as Joins.
You can get a better idea of all the possibilities by exploring this page https://dev.mysql.com/doc/refman/8.0/en/select.html, plenty of fairly easy to follow examples.

What's the regex to convert "SELECT whatever FROM" to "SELECT COUNT(*) FROM"?

I basically want to be able to take any non nested SQL string and convert it to the SQL to get the count all with the same regex.
It just has to be able to match anything between SELECT and FROM one time and replace with count(*) but I haven't allocated experience points to leveling up my regex yet.
i.e.
SELECT col1, col2 FROM my_table where..." to "SELECT count(*) FROM my_table where...
Or
SELECT * FROM my_table where..." to "SELECT count(*) FROM my_table where...
Why not just do
SELECT COUNT(*) from ( <insert original sql here> ) as X
For a regex, you could use a simple one demonstrated here.
Essentially we replace whatever is in between SELECT and FROM with COUNT(*). Details are at the link as well.
Note that this will assist you in your thinking but is no way tested in depth. Please run some tests on your own.
You could also use the link to generate code in Python, JavaScript etc.
Edit 1: the link was enclosed as a code snippet and so did not work. Removed the code meta tag.
I always believe regex should be used when you have no simpler or any option at all. In your case, you can do this with simple SQL logic instead of regex. You can pass the original query as-is to your MySQL procedure or whatever and do this:
set #inputQuery = 'SELECT col1, col2 FROM my_table where id = 1'; -- you will pass this
set #startIndex = locate('select', #inputQuery) + char_length(rtrim('select'));
set #endIndex = locate('where', #inputQuery);
set #subString = substring(#inputQuery, #startIndex, #endIndex - #startIndex);
set #finalQuery = replace(#inputQuery, #subString, ' count(*) ');
select #finalQuery;
Output:
SELECT count(*) where id = 1
In MySQL, you can use SQL_CALC_FOUND_ROWS and then FOUND_ROWS() with any query. So:
SELECT SQL_CALC_FOUND_ROWS . . .
FROM . . .
Then to get the number of rows:
SELECT FOUND_ROWS()
This is defined in the documentation.

How to SELECT w/ LIKE and a '_' delimiter

I have a table with a name field that can have values like:
CHECK_5_20170909
CHECK_1_20170809
CHECK_11_20170809
CHECK_11_20170909
I would now like to query all fields that have a _1_ in the name, but ONLY them.
I tried this: SELECT * FROM tblName WHERE name LIKE '%_1_%';
but that shows me _11_ AND _1_ in my results.
When I try it with CHECKWHATEVER1WHATEVER20170909 and LIKE %WHATEVER1WHATEVER% it works, are there any special rules for _ in a MySQL Query?
Changing it to another delimiter in the MySQL DB would create a hell of work, is there any "workaround"?
You need to add a '\' before each underscore, otherwise its interpreted as a random "wildcard" character.
select * from
(
select 'CHECK_5_20170909' col
union
select 'CHECK_1_20170809'
union
select 'CHECK_11_20170809'
union
select 'CHECK_11_20170909'
) t
where col like '%\_1\_%'
try this using REGEXP
SELECT * FROM tblName WHERE name regexp '_1_';
it will return exact matches record from column for more reference read here

select data mysql

i have in my table places named field. there are space separated values(there are problem to store csv value in one field). now i want to fire query like below. how i can do ??
select * from tablename where variablename in places
i did try this way but it shows syntax error.
select * from tablename where variablename in replace(places,' ',',')
### places ###
bank finance point_of_interest establishment
Use FIND_IN_SET
For comma separated
SELECT *
FROM tablename
WHERE ( FIND_IN_SET( 'bank', variablename ) )
Refer : SQL Fiddle
For space separated
SELECT *
FROM tablename
WHERE ( FIND_IN_SET( 'bank', replace(variablename,' ',',') ) )
Refer : SQL Fiddle
The best solution would be to normalise your data structure and do not have a single field storing multiple values.
You can make a query work without normalisation, but any solutions would be lot less optimal from a performance point of view.
Use patter matching with like operator:
... where fieldname like '% searched_value %'
Use the replace() function and combine it with find_in_set():
... where find_in_set('searched_value',replace(fieldname,' ',','))>0
Hi I think your problem comes from the usage of IN
IN for MySql is used like this
SELECT *
FROM table_name
WHERE column_name IN (bank,finance,point_of_interest, establishment);
In case of you want to select places you need to specify each place into value like

SQL Query to search partial data in one field

I have the following data in mysql:
file-id
32-534
32-536
32-537
32-584
32-594
46-865
46-863
46-837
46-867
I want to write SQL query to enlist all the data with either 32- or 46-. How can I do that?
Select * from TABLE WHERE file-id = ????
This should work:
SELECT * FROM TABLE WHERE 'file-id' LIKE '32-%' OR 'file-id' LIKE '46-%';
SELECT * FROM table_name WHERE file-id REGEXP '^32' OR file-id REGEXP '^46';
Try:
SELECT * FROM table_name WHERE file-id REGEXP '^(32|46)';