I would love to do a MySQL query like this. I know the syntax is incorrect and I can't use an "if" at the beginning of a query like this. This is for Tableau custom SQL query, by the way. I'd like to have a negative value for AccountID mean displaying all Accounts, and a positive value mean displaying either the account associated with the positive value, or displaying nothing if there is no account associated with the positive value.
if <Parameters.AccID> < 0
select * from Accounts
else
select * from Accounts where id = <Parameters.AccID>
Can someone help me do this with correct syntax?
Since I must use Tableau Desktop as the platform for this, I only have access to query syntax.
You can run such a multi query, if you need it.
SELECT if (Parameters.AccID < 0, #q := 'select * from Accounts',#q := CONCAT('select * from Accounts where id = ',Parameters.AccID));
PREPARE stmt from #q;
EXECUTE stmt;
DEALLOCATE PREPARE stmt
Related
I have the following small subquery in query in stored procedure.
(select f_cnt from results limit (i-1)*10,i*10)
But there is the syntax error:
"(" is not valid at this position, expecting an identifier
So, the question is: do I have a possibility to use brackets and/or arithmetic operators in LIMIT clause?
Documentation says I can use local variables in LIMIT clause within stored procedure. Do I really need to declare and set different variables for this case?
Just in case, link for the code of stored procedure.
You can't do arithmetic at that point
So do instead
SET #sql := CONCAT("SELECT * FROM TEsttable WHERE id In(select f_cnt from results limit ",(i-1) * 10,",",i*10,")");
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Which will produce
SELECT * FROM TEsttable WHERE id In(select f_cnt from results limit 90,100)
I'm trying to use the result of a custom MySQL function in the WHERE IN clause of a query:
SELECT *
FROM project p
WHERE p.category_id IN (getCategorys(1))
The result of the custom function is as follows:
SELECT getCategorys(1)
1,2,3,4,5
Unfortunately, this does not give the same result as:
SELECT * FROM project p WHERE p.category_id IN (1,2,3,4,5)
The query using the custom function only returns results where category_id = 1
What am I missing here?
If you use the FIND_IN_SET() solution that #Uueerdo mentions, it'll always do a table-scan. It can't use an index.
The only way to make this work with index optimization is to fetch the string of category id's before you prepare the query. In other words, do two queries.
Something like this (but I haven't tested it):
SELECT getCategorys(1) INTO #tmp;
SET #sql = CONCAT('
SELECT *
FROM project p
WHERE p.category_id IN (', #tmp, ')');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
This is technically a case of SQL injection, even though it's using content that you produce from your own function. Be sure you have complete control over what your getCategorys() function returns.
For example, can the function ever return an empty string? That would result in IN ( ) which is a syntax error.
The form the results from the custom function take is not obvious from the question; but IN takes lists or results, not strings. I am guessing the function returns a string.
It's not ideal from a performance perspective but FIND_IN_SET may be easier to use to produce the behavior you want.
I need to find top 10% (note its not top 10 its top 10%) students of a class.
My tries-
select *
From alphatable
LIMIT 0, (SELECT Floor(26*0.01))
But it is throwing error, let me know what I am doing wrong?
Fiddle- Fiddle
Edit
Note- This is a dummy data..my actual class data contains 96 students..so let me know the formula of finding is correct or not? (count_student_number*.01)
Try following query and formula for finding top 10% students:
SELECT Floor(100 * 0.1) INTO #my_limit;
PREPARE STMT FROM 'SELECT * FROM alphatable LIMIT ?';
EXECUTE STMT USING #my_limit;
NOTE: Please add other required filters in query and also recheck your formula.
Taking Samsonjet's answer into account try it like this:
SELECT FLOOR(
(SELECT 10*(SELECT COUNT(*)
FROM alphatable)/100))
INTO #top_10_percent;
PREPARE STMT FROM 'SELECT *
FROM alphatable
ORDER BY occurnence LIMIT ?';
EXECUTE STMT USING #top_10_percent;
It will calculate your top 10 percent by the given table and floor the result.
check your fiddle here: http://www.sqlfiddle.com/#!2/f9fb0b/74
I have a query that picks out a specific row/column from a large database. Lets say that the value returned is '53.'
I need to get:
1. The row that is 3000 rows above this value.
2. The row that is 3000 rows below this value.
If there turn out to be only 2000 rows above the value, then I need to add the difference onto the second query.
Ex.
1. Find 3000th value up (turns out that only 2000 values are present)
2. Find 4000th value down.
Here is how I did it (this is in a stored procedure):
SET #s1 = CONCAT('INSERT INTO List1(STD) SELECT t1.STD FROM ',t1,' AS t1 USE INDEX(STD) WHERE t1.STD < ',inp1,' order by STD DESC limit ', inp2);
PREPARE stmt FROM #s1;
EXECUTE stmt;
SET #lim = inp2+(inp2-(SELECT FOUND_ROWS()));
SET #s2 = CONCAT('INSERT INTO List1(STD) SELECT t1.STD FROM ',t1,' AS t1 USE INDEX(STD) WHERE t1.STD >=', inp1,' order by STD ASC limit ?');
PREPARE stmt FROM #s2;
EXECUTE stmt USING #lim;
SET #minSD1 = (SELECT MIN(STD) FROM List1);
SET #maxSD1 = (SELECT MAX(STD) FROM List1);
This seems awfully round-about... is there no better way?
Also, is there really no way to use a variable table name in a stored procedure without creating ANOTHER stored procedure (with the PREPARE keyword)?
In SQL, the concept of "3000 rows above/below a given point" exists ONLY in the context of an ordered resultset, and is not defined in the database. Unless there's an algorithmic process, based on a key, to determine what is "n rows above/below" a given point, then you are stuck with actually reading the rows and counting, which is what your solution seems to attempt. I didn't verify that it actually does what you want, but either this approach or one based on cursors and counting rows is the only way to get this done.
What I'd like to do is execute a MySQL query containing a where clause ("result query") that is stored in a column in the database. This column, containing the query, is a result of another query ("original query").
The catches:
The result query's where clause can contain a variable value (or two)
I don't know what the result query will be when executing the original query, so I cannot pass along the variable's value
(The list of result queries as well as the variables in the where clauses will be defined by me, so I will will have a list of all the possible variables.)
Essentially, I need to be able to correlate that variable with any number of other values, one example: a user_id, within the database.
original_query_table | result_query_table
--------------------------------------------------------------
other_id result_query_id | result_query_id result_query
1 1 1 "SELECT ... WHERE user_id = :id "
I know how to do this with two separate queries, but the question is whether this is possible with only one query?
I would do something like this:
SELECT 'select * from table_a where col_a = ?' INTO #query, 1 into #param1 FROM dual;
PREPARE stmt FROM #query;
EXECUTE stmt USING #param1 ;
So converting that into your tables, I guess would look like:
SELECT a.result_query INTO #query, b.result_query_id INTO #param1 FROM result_query_table a, original_query_table b where a.result_query_id = b.result_query_id;
PREPARE stmt FROM #query;
EXECUTE stmt USING #param1 ;
Will you know how many parameters the where clause will need? If that's dynamic, then things could get a bit tricky.