MySQL: Match against dynamic values - mysql

I have a list of values in a table column that I need to match against table names, preferably just using an SQL statement.
If the values were static, I suppose the SELECT statement would be something like this:
SELECT table_name FROM information_schema.TABLES WHERE
match(table_name) against('124512' +'36326' +'23636' IN BOOLEAN MODE)
However, I need to match against dynamic values coming from a SELECT statement:
SELECT tableid FROM databaseName.tableOverviewTableName
WHERE template = 'templateName')
The tableid above is contained in the table_name for the tables that I want.
Is this possible to achieve with an SQL statement?

You can do this via Prepared statement (not directly via a query)
SET #tq = (SELECT tableid FROM databaseName.tableOverviewTableName WHERE template = 'templateName'));
SET #stmq = CONCAT('SELECT * FROM ', #tq);
Prepare stmt FROM #stmq;
Execute stmt;
DEALLOCATE PREPARE stmt;

Related

How to set a local list/tuple variable in mysql

Is there a way to do the following in mysql?
SET #studios = ('Disney', 'Warner Bros.', 'Fox');
SELECT * FROM movies WHERE provider IN #studios;
When I try doing the above I get the error:
Operand should contain 1 column(s)
The error is coming from your initial assignment. You cannot assign lists to variables.
The only way of doing this in MySQL is to either create a temp table to hold the values, and then do ... IN (SELECT someVal FROM thatTemp), or to dynamically create the query with the values directly in the query string.
Example temp table creation:
CREATE TEMPORARY TABLE `someTemp` ( someVal VARCHAR(16) );
INSERT INTO `someTemp` (someVal) VALUES ('a'), ('b'), ('c');
SELECT * FROM myTable WHERE myField IN (SELECT someVal FROM someTemp);
DELETE TEMPORARY TABLE `someTemp`;
Alternatively, there is also FIND_IN_SET, which could be used like this:
SET #list = 'a,b,c';
SELECT * FROM myTable WHERE FIND_IN_SET(myField, #list) <> 0;
but this method probably has extremely poor performance (and may not be useable if your "myField" values may contain commas).
It is not possible to set a tuple/list/array in a user-defined variable in MySQL. You can use Dynamic SQL for the same:
-- we use single quotes two times to escape it
SET #studios = '(''Disney'', ''Warner Bros.'', ''Fox'')';
-- generate the query string
SET #query = CONCAT('SELECT * FROM movies WHERE provider IN ', #studios);
-- prepare the query
PREPARE stmt FROM #query;
-- execute it
EXECUTE stmt;
-- deallocate it
DEALLOCATE PREPARE stmt;
You could concatenate your list to a string, and use FIND_IN_SET as your criteria. Might not be super efficient, but makes the code quite easy to read and maintain.
Looks like this:
SET #studios = CONCAT_WS(',',
'Disney',
'Warner Bros.',
'Fox'
);
SELECT * FROM movies
WHERE FIND_IN_SET(provider, #studios) <> 0;

use result string from one table as column names for another query

I am trying to trying to simplify the following query :-
SELECT id, m_field_id_46 AS Liverpool,m_field_id_47 AS London,m_field_id_48 AS Belfast FROM member_data
In a way i can dynamically create the column names
SELECT id, (SELECT GROUP_CONCAT('m_field_id_',m_field_id,' AS ',m_field_label) FROM member_fields) as dist FROM member_data
However this is not working. Please help
i got it working by looking at another answer from stackoverflow: -
SET #listStr = ( SELECT GROUP_CONCAT('md.m_field_id_',m_field_id,' AS `',m_field_label,'`') FROM member_fields );
SET #query := CONCAT('SELECT ', #listStr, ' FROM member_data');
PREPARE STMT FROM #query;
EXECUTE STMT;

SQL query to find duplicate rows, in any table in Mysql database

I'm looking for a schema-independent query. The query should be equally capable of catching duplicate rows in either table in a database.I have number of tables without primary key. I have found a result for sql server [which i have most experience] but looking for same thing in mysql
Use dynamic SQL to generate the query using the column information in information_schema:
SET #tablename = 'yourTable';
SET #sql = (
SELECT CONCAT('SELECT *
FROM `', table_name, '`
GROUP BY ', GROUP_CONCAT(CONCAT('`', column_name, '`')), '
HAVING COUNT(*) > 1')
FROM information_schema.columns
WHERE table_name = #tablename );
PREPARE stmt FROM #sql;
EXECUTE stmt;

how to select data from table which is a row data in another table

the exp_lab_mapping contains the entry
lab_id->cse05
exp_id->CSE0501
and I want to select the data from table CSE0501 by writing query
select * from (select exp_id from exp_lab_mapping where lab_id='cse05') as a;
but it's not giving me the data of CSE0501 instead it's giving output as
Output:-
----------
exp_id
CSE0501
in this case, you need to create a dynamic sql since, if i correctly understood your problem, you want to select records from which the name of the table is a row from table exp_lab_mapping. (which is also a bad schema design)
SET #sql = (SELECT exp_id FROM exp_lab_mapping WHERE lab_id = 'cse05');
SET #sql = CONCAT('SELECT * FROM ', #sql);
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SQLFiddle Demo

Need help with MySQL query

I am trying to execute the following query statement contained within a Stored Procedure -
Where all P... are parameters to SP (ex PInitialDateFrom).
SET #stmt_text = CONCAT('SELECT AccountID, Firstname as ClientName, EmailID
, ProductID, InitialPurchaseDate as Purchasedate
FROM client_account
WHERE IsRemoved = 0
AND (InitialPurchasedate between ? and ?)
AND ProductId IN (?)');
PREPARE stmt FROM #stmt_text;
SET #initDt1=PInitialDateFrom, #initDt2 = PInitialDateTo, #inlist=PIDs
, #stmt_text = null;
EXECUTE stmt USING #initDt1, #initDt2, #inlist;
DEALLOCATE PREPARE stmt;
I am passing PID's as a string of ids like 1,2,3
When I try to execute the statement, only the first id is considered. For ex. 1,2,3 is used only 1 is taken, if 3,2,1 is used only 3 is taken.
Can anybody tell what's wrong with this query?
You can't use this part:
and ProductId in (?)
Remember: SQL parameters are not like C macros where you are just doing string replacements. They are more than thar: When you use ?, one and only one parameter gets bound. So, when you try to bind 1,2,3 to that parameter, it's not like you are trying to bind three values but only one.
If your list is going to be of fixed size, you could use:
and ProductId in (?,?,?)
Otherwise, I don't think you will be able to use parameters for that clause. Maybe doing something like:
set #initDt1=PInitialDateFrom,
#initDt2 = PInitialDateTo,
#inlist=PIDs,
#stmt_text = null;
set #stmt_text =
concat('Select AccountID, Firstname as ClientName, EmailID, ProductID
, InitialPurchaseDate as Purchasedate from client_account
where IsRemoved=0 and (InitialPurchasedate between ? and ?)
and ProductId in (', #inlist, ')');
prepare stmt from #stmt_text;
execute stmt using #initDt1, #initDt2;
deallocate prepare stmt;
Make sure you sanitize your input for PIDs so you don't add SQLInjection vulnerabilities to your code.
You should put it like this:
and ProductID = (?)
I hope it works.