Multiple values in MySQL variable - mysql

The following works as expected when there is a single value stored in a variable.
SET #a := "20100630";
SELECT * FROM wordbase WHERE verified = #a;
But it does not work when there are multiple values stored in a variable.
SET #a := "'20100630', '20100701' ";
SELECT * FROM wordbase WHERE verified in (#a);
Do I need to use prepared statements for this?

There's good solution described here: https://stackoverflow.com/a/11957706/1523961
So you can use something like this:
SET #a := '20100630,20100701';
SELECT * FROM wordbase WHERE FIND_IN_SET(verified, #a);
Also, if you're selecting the ids for #a from another table, you can come up with the following:
SET #a := (SELECT GROUP_CONCAT(id) FROM someTable where yourBooleanExpressionHere);
SELECT * FROM wordbase WHERE FIND_IN_SET(verified, #a);

You cannot (as far as I am aware) store multiple values in a MySQL user defined variable. What you have done is create a string which contains:
'20100630', '20100701'
That is not two separate values, but a single string value, just as this is a single string value:
SET #a := "It's a single string, and that's the problem";
You need to use two separate variables, or prepare a statement, like this:
SET #a := "20100630";
SET #b := "20100701";
SET #sql = CONCAT(
'SELECT * FROM wordbase WHERE verified IN (',
#a,
',',
#b,
')'
);
SELECT #sql;
+--------------------------------------------------------------+
| #sql |
+--------------------------------------------------------------+
| SELECT * FROM wordbase WHERE verified IN (20100630,20100701) |
+--------------------------------------------------------------+
PREPARE stmt FROM #sql;
EXECUTE stmt;
But that's kinda messy. Why do you need to use variables?

Using GROUP_CONCAT and GROUP BY one could pull all values ( i.e. an id ) into a variable like so:
SET #var := (SELECT GROUP_CONCAT(id) FROM `table` WHERE `verified` = #verified GROUP BY verified);

Something like this should work. Is it ok to use prepared statements to create temporary tables like this?
SET #a := "'20100630', '20100701'";
SET #sql = CONCAT('create temporary table pn1 SELECT * FROM wordbase WHERE verified IN (', #a, ')');
PREPARE stmt FROM #sql;
EXECUTE stmt;
select * from pn1;

SELECT GROUP_CONCAT(field_table1 SEPARATOR ',') FROM table1 into #var;
then
SELECT * FROM table2 WHERE field_table2 in(#var);
works fine for me

FIND_IN_SET(column to find in , string csv) is a very handy method in case you have the string list of CSV:
SET #a := "'20100630', '20100701' ";
SELECT * FROM wordbase WHERE FIND_IN_SET(verified, #a);
if your variable is also coming from query then use this to set #a
SET #a := (SELECT GROUP_CONCAT(`id`) FROM `table`);

If you need to use your variable for a select or delete you can use select in the select:
delete from MPCurrentPayEntitlementAccrual where CurrentPayEntitlementID in ( select CurrentPayEntitlementID from MPCurrentPayEntitlement where PayRunID=myPayRunId by PayRunID desc);
That worked perfectly for me

Related

Creating a subquery within the From clause in order to refer to a archived table

I'm trying to run a simple count(*) query to check the total number of entries in a table that gets archived everyday. However, I need this query to function everyday within my reporting functions so it should be useful everyday.
Unfortunately, when I run the query it simply treats it either as an error or a subquery with no data inside it. Here's my troubleshooting query:
SELECT * FROM
SELECT CONCAT('archivedtable__', REPLACE(SUBDATE(CURRENT_DATE(), 1), '-
',''));
SELECT * FROM (
SELECT CONCAT('archivedtable__', REPLACE(SUBDATE(CURRENT_DATE(), 1), '-
',''))) subquery;
The first gives an error, the 2nd will just return archivedtable__20190813 which is the correct name but doesn't actually get it to refer to the table.
You may think of using Prepared Statements. For your hint here is an example:
Pre-Requisite: Create two tables with the dates of last 2 days i.e yesterday and day before yesterday.
SET #prefix := 'archivedtable__';
SET #date1 := REPLACE(SUBDATE(CURRENT_DATE(), 1), '-','');
SET #table1 := concat(#prefix, #date1);
SET #date2 := REPLACE(SUBDATE(CURRENT_DATE(), 2), '-','');
SET #table2 := concat(#prefix, #date2);
set #qry:= concat('SELECT COUNT(*) as t1,(SELECT COUNT(*) FROM ', #table1, ') as t2 FROM ', #table2);
prepare stmt from #qry;
execute stmt;
You can build the SQL as a VARCHAR (or NVARCHAR) and then use sp_executesql.
Like this:
DECLARE #tblCount INT
DECLARE #tblName AS NVARCHAR(100) = CONCAT(.....)
DECLARE #countSql AS NARCHAR(200) = N'SELECT #cnt = COUNT(*) FROM ' + #tblName
DECLARE #ParmDefinition NVARCHAR(500) = N'#cnt INT OUTPUT'
EXECUTE sp_executesql #countSql, #ParmDefinition, #cnt = #tblCount OUTPUT;
SELECT #tblCount;

how to get data from dynamic table in sql

How can I get data from chosen table of my database?
I'm going to work with database in c# application and I have the database includes that tables:
MyTable1;
MyTable2;
...
And I have tbl variable that is equal to tbl = "MyTable2";. I want to execute the code as following:select * from tbl
I try to execute this code:
SELECT *
FROM (
SELECT TABLE_NAME
FROM information_schema.tables
WHERE TABLE_NAME = 'MyTable1'
);
But the code returned error that Every derived table must have its own alias
I want to get all data from table whose name is equal to my variable (tbl) and its value can also be changed. How can I do it?
You might be able to do this using a prepared statement in MySQL:
SELECT TABLE_NAME
INTO #table
FROM information_schema.tables
WHERE TABLE_NAME = 'MyTable1';
SET #query = CONCAT('SELECT * FROM ', #table);
PREPARE stmt FROM #query;
EXECUTE stmt;
SELECT *
FROM (
SELECT TABLE_NAME
FROM information_schema.tables
WHERE TABLE_NAME = 'MyTable1'
) AS Blah
Try this:
DECLARE #SELECT nvarchar(500)
SET #SELECT = 'SELECT * FROM ' + #tbl
EXECUTE sp_executesql #SELECT

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;

Table name as field

Is it possible to query a table whose name comes from a sub-query?
For example.,
SELECT * FROM <TABLE_NAME IS <SUB_QUERY>>
select * from (
(select distinct(name) from category where id = 3 limit 1) CAT);
INNER QUERY RESULTS --> DEPARTMENT;
So it has to fetch from department table.
Using Mysql as DB.
You should use Prepared Statements.
In your case it should be:
select #name := name from (
(select distinct(name) from category where id = 3 limit 1) CAT);
set #sqlquery := 'select * from ' . #name ;
prepare qry from #sqlquery ;
execute qry;
deallocate prepare qry;
This might be helpful SQL Syntax for Prepared Statements
In two words: you can execute sql commands specified in varchar variables which can be produced by concatenation and other stuff.

MySQL: alias column name question

Is it possible to alias a column name with the result of a simple SELECT query.
This doesn't work:
SELECT `hlevel1` AS (SELECT `level1` FROM `hierarchy_labels` LIMIT 1) FROM `hierarchy`;
Any Suggestions?
You can't do this.
Aliases are used to rename a field or to name a calculated field.
If you simply want your results to be named 'hlevel1', you may want to try this:
SELECT level1 as hlevel1 FROM hierarchy_labels LIMIT 1
Use a prepared statement.
SELECT `level1` INTO #x FROM `hierarchy_labels` LIMIT 1;
SET #s = CONCAT('SELECT `hlevel1` AS `', #x, '` FROM `hierarchy`');
PREPARE s FROM #s;
EXECUTE s;
DEALLOCATE PREPARE s;