Find top 10% students in a class using mysql - mysql

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

Related

Syntax for Branching SQL Query Based on a Parameter

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

How to create two tables with first 75% and remaining 25% of another table in MySQL?

I wrote this expecting it would work but LIMIT and OFFSET doesn't allow me do any calculations by giving error : "Error Code: 1327. Undeclared variable: ceil
"
INSERT INTO as24t
SELECT * FROM as24 LIMIT ceil(count(*)*3/4);
INSERT INTO as24v
SELECT * FROM as24 LIMIT floor(count(*)/4) OFFSET ceil(count(*)*3/4);
All I want to do is take first 3/4 of as24 table and insert into as24t and remaining 1/4 to as24v, considering some tables have odd number of records. Also, I don't want to calculate it and hardcode numbers into query because I have 40+ tables to divide and I feel there must be a clever way.
Please find something unique to order by in order to verify that you get complement sets.
set #numrows_25=(select count(*) from as24) * 0.25;
PREPARE STMT FROM 'INSERT INTO as24v SELECT * FROM as24 order by ... LIMIT ?';
EXECUTE STMT USING #numrows_25;
PREPARE STMT FROM 'INSERT INTO as24t SELECT * FROM as24 order by ... LIMIT 9999999999 OFFSET ?';
EXECUTE STMT USING #numrows_25;

Limit by RAND without random order

I am trying to select records in order but limited randomly.
SELECT * FROM tm_winners WHERE paid_out=0 ORDER BY DESC LIMIT RAND(4,8)
However it seems I cannot have a random limit of rows. I am bassiclty trying to grab between 4 and 8 rows but NOT randomly, just limited randomly.
You'll have to use a prepared statement to use a variable amount in the LIMIT clause.
SET #lrand = FLOOR(4 + RAND() * (8 - 4));
PREPARE STMT FROM 'SELECT * tm_winners WHERE paid_out=0 ORDER BY DESC LIMIT ?';
EXECUTE STMT USING #lrand;
Personally, even if its not the cleanest way, Id set a var previous to the select statement and Limit by the var.
$randomVar = rand(4, 8);
$sql = 'SELECT * FROM tm_winners WHERE paid_out=0 ORDER BY DESC LIMIT 0,'.$randomVar;
Clearly if you wanted randomness within the actual results, you could clearly reintroduce the rand() within the statement
Hope it helps
Will

Issue with using MAX()

I was answering a question on SO that encountered this issue.
Why I can't use MAX() within a LIMIT?
SELECT *
FROM table
ORDER BY id DESC
LIMIT 0, MAX(id)
Or
SELECT *, MAX(id) AS m
FROM table
ORDER BY id DESC
LIMIT 0, m
Both give a similar syntax error:
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'MAX(id)' at line 4
Wanted query:
SELECT *
FROM table
ORDER BY id DESC
LIMIT 0, MAX(id)-5
MAX() is an aggregate function over the result rows, but LIMIT is a clause that constrains the number of result rows. In short, you cannot use a function that depends on the result rows while you are still determining which rows will be in the result -- that simply doesn't make any sense.
According to the documentation, LIMIT arguments must either be integer constants or parameters of a prepared query (emphasis mine):
LIMIT takes one or two numeric arguments, which must both be nonnegative integer constants (except when using prepared statements).
The syntax specification simply does not allow a column or function to be used. You would have to pre-compute the value and then use it in a prepared query (or by string substitution, though I would avoid that).
Based on the query you gave in your question:
SELECT *
FROM table
ORDER BY id DESC
LIMIT 0, MAX(id)-5
I suspect that this is the query you actually want:
SELECT *
FROM table
WHERE id <= (SELECT MAX(id) FROM table) - 5
ORDER BY id DESC
Even if it were valid, the first query you gave will not do what you expect if there are gaps in the sequence of the id column (for example, if a row was deleted).
An alternative if you want to get your desired result is to create a dynamic sql.
SET #maxID = (SELECT MAX(ID) FROM tableName);
SET #sql = CONCAT('SELECT *
FROM tableName
ORDER BY ID DESC
LIMIT 0,', #maxID);
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
The function MAX cannot be used on the limit.
Here is the documentation:
http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_max
The count argument in the limit should be a value so you cannot execute that in one step. Here is the select documentation:
http://dev.mysql.com/doc/refman/5.0/en/select.html
You can do is:
SET #a=(SELECT MAX(ID) FROM table);
PREPARE STMT FROM 'SELECT * FROM table ORDER BY id DESC LIMIT 0, ?';
EXECUTE STMT USING #a;
So it is a tree step here. Get max in a variable. Prepare a statement and than execute it applying the variable to the statement.
You can use the HAVING clause with MAX(id) to obtain your desired result
SELECT *
FROM table1
HAVING id<((SELECT Max(id) FROM table1)-5)
ORDER BY id DESC
Fiddle http://sqlfiddle.com/#!2/16e50/3
ISSUE IS WIth your query::
Select
*
from
myTable,
(SELECT MAX(id) as n
FROM table) temp
ORDER BY id DESC
LIMIT 0, temp.n

SQL / Limit (another query)

I have 2 tables. One of them holds the limit numbers.
And i am trying to run an sql like
SELECT * FROM table WHERE x='1' LIMIT (another query)
The Select TOP clause limit the number of rows. You can put an expression in it
http://msdn.microsoft.com/en-us/library/ms189463.aspx
In MySQL you can't do that using regular querys.
LIMIT clause does not allow variables. LIMIT clause only accepts constant numbers.
You have to use Stored Procedures instead regular querys.
Try use something like this inside an SP code:
DECLARE offset bigint
SELECT your_field INTO offset FROM your_table where your_conditions
SELECT * FROM other_table LIMIT offset;
Use a prepared statement:
PREPARE stmt FROM "SELECT * FROM table WHERE x='1' LIMIT ?";
SET #limit = (another query);
EXECUTE stmt USING #limit;
\You do what I have suggested to several people is generate SQL from a select statement and then execute that. Here is my solution:
SELECT "select * from other_table LIMIT ", your_field
FROM your_table where your_conditions
Then execute this new SQL. Of course this works best in UNIX/Linux and with a scripting language.