This question already has an answer here:
Mysql Select some random rows and plus one specific row
(1 answer)
Closed 9 years ago.
Is it possible to get a specific value (like ID = 5) and in addition to that, two or three other random values from the same table?
Here's my query:
SELECT name, solution, MAX( solution )
FROM tracks
WHERE id !=5
GROUP BY name
ORDER BY RAND( )
LIMIT 0 , 30
What I want to do:
I have a quiz where I need to get three answers from the database. In my first query I'm getting the actual answer and in the second (the query above) I get the other two answer that are NOT the actual answer (ID != ).
The problem is, in my table, 4 values are the same, they have the same name, so if my acutal answer is ID = 5, there is the possibility that the query above will select the ID with 9 (it's the same name as ID = 5).
How can I avoid that?
Thank you!
Perhaps you could add a subquery to your where clause to lookup all solutions that are not the id and do not have the same solution name:
SELECT name, solution, MAX( solution )
FROM tracks
WHERE id !=5
--check that the id is not in the subquery and the name doesnt match:
AND id not in (select id from tracks t where id!=5 and t.name <> name)
GROUP BY name
ORDER BY RAND( )
LIMIT 0 , 30
Random results are random. If you want to ensure that you don't get results with the same name as the answer, you have to filter by name.
SELECT name, solution, MAX(solution)
FROM tracks
WHERE id != 5 AND name != (SELECT name FROM tracks WHERE id = 5)
GROUP BY name
ORDER BY RAND()
LIMIT 0 , 30
Yes, it's possible. Use UNION for that. (sqlfiddle here)
SELECT * FROM ( (
SELECT id, name, max(solution) as solution
FROM tracks
WHERE id = 5
GROUP BY name
LIMIT 0, 1
)
UNION (
SELECT id, name, solution
FROM tracks
WHERE id != 5
GROUP BY name
)) tmp ORDER BY RAND() LIMIT 0, 3
Related
What Im Trying to achieve is selecting multiple rows randomly where a certain column is different from the last for example
SELECT * FROM mytable WHERE `column_for_duplicate_values` != '$thelastkey' ORDER BY RAND() LIMIT 10
the column for multiple values would hold for example:
1 , 1 , 1 , 1 , 2, 5 , 6, 6 , 6 , 6 , 6 , 11 , 11 , 11 , 19
and I want to select 1 from each. So I would get
1 , 2 , 5 , 6 , 11 , 19
The main problem with my solution may be that it's
slow
not applicable
You need to have a primary unique id in your mytable
SELECT * FROM mytable WHERE id IN (
SELECT id FROM (
SELECT id, column_for_duplicate_values
FROM mytable ORDER BY RAND()) AS rand
GROUP BY column_for_duplicate_values
ORDER BY RAND()) LIMIT 10;
The main concept is to first get a random list of all values with their id and the column you want to have unique values.
From this result we group by the value we only want to have once and only return the id. The main table will then select 10 random id's form this list.
I tried it with one of my db's. Should work with any table that has a unique id and some random other column.
If you append ORDER BY id ASC will also sort the id's.
i am developing an online test system in php,mysql..when a student submits a test its marks are calculated on the basis of correct answers matched from database using following query..
SELECT qa.question_id, qa.test_id, uta.user_answer,uta.user_id, qa.type,
qa.answers correct_answer,
CASE WHEN uta.user_answer = qa.answers THEN 'correct' ELSE 'incorrect' END
AS count(status)
FROM questions_answer qa
LEFT JOIN
(
SELECT user_id, type, test_id, question_id,
GROUP_CONCAT(answers ORDER BY answers) AS user_answer,
timestamp from user_test_answers
WHERE test_id = '1'
GROUP BY user_id, question_id
) uta
ON qa.question_id = uta.question_id
where qa.test_id=1 GROUP BY uta.user_id
my problem is:
I want to count the no of times "correct" appear in field STATUS field in table...
these no of correct answers are passed as an argument in a function.... i cant get results of other students....so i want to compare on the basis of CORRECT string appearing in field on the basis of user_id and display top 3 scorers.. How to do this "top 3 scorers in a particular test"..
I am a newbie to MySQL..
If I had to guess, the following should give you what you want. Change:
CASE WHEN uta.user_answer = qa.answers THEN 'correct' ELSE 'incorrect' END AS count(status)
to
sum(uta.user_answer = qa.answers) as NumCorrect
This question already has an answer here:
How to find the previous and next record using a single query in MySQL?
(1 answer)
Closed 8 years ago.
mytable
id name
------- --------
1 James
2 John
3 Edward
4 Bill
above is my table, I'm trying to build a query which can select both the greater than and less than value. For example $current_id = 3, so what I need to select is 2 and 4 from the table with a single query. I can obtain the one(less than or greater than) value but not sure how to combine the query to obtain both.
Query
SELECT mytable.id FROM mytable WHERE id > $current_id;
(SELECT id
FROM mytable
WHERE id > $current_id
ORDER BY id ASC
LIMIT 1)
UNION
(SELECT id
FROM mytable
WHERE id < $current_id
ORDER BY id DESC
LIMIT 1)
SELECT mytable.id FROM mytable
WHERE id = $current_id +1
OR id=$current_id -1;
Here we are using OR gate that will check both conditions and it will run both conditions, if both are passing then it will show the result of both conditions or if any one conditions is passing then it will show the result only of that condition that is passing.
I was trying to create a single SQL query to return what I need, instead of creating 2 querys, but I need to use the result of one of the querys as the offset of the other one.
My table has user answers with scores, each user may have multiple answers in that table. And I want to calculate the middle point of the table of ordered scores.
Example:
User answers:
User 1 - 5 points
User 1 - 15 points
User 2 - 8 points
User 3 - 12 points
Ranking Table:
User 1 - 20 points
User 3 - 12 points < Middle point
User 2 - 8 points
Solution:
The first query calculates the middle point:
SELECT CEILING(count(Distinct(id_user)) / 2) as position
FROM us_user_response
where id_round=1
Query result:
position : 2
This second query creates the ordered ranking table:
SELECT sum(points) as score
FROM us_user_response
where id_round=1
GROUP BY id_user
Order by score DESC
Now I want to create one big query that returns the score of the middle user, I just need to use the first query result as offset of the second query:
SELECT sum(points) as score
FROM us_user_response
where id_round=1
GROUP BY id_user
Order by score DESC LIMIT 1
OFFSET (SELECT CEILING(count(Distinct(id_user)) / 2) as position
FROM us_user_response where id_round=1)
Of course, this doesn't work, is there any way to use a result as offset?
EDIT:
The queries work nice! My question is if there is any way to use the result of a query as the offset of another. So I could accomplish this in one single query.
Try something like this:
SET #line_id = 0;
SET #line_offset = (
SELECT CEILING(count(Distinct(id_user)) / 2) as position
FROM us_user_response
WHERE id_round = 1
);
SELECT sum(points) as score,
IF((#line_id := #line_id + 1) = #line_offset, 1, 0) AS useit
FROM us_user_response
WHERE id_round = 1
GROUP BY id_user
HAVING useit = 1
ORDER BY score;
I am developing a Online Exam Application where I have a question master table which contains a field ( name : qtype ) containing the data for the type of question. A question type can be either of following three types :
single
multiple
desc
The application is generating a random question paper from this master table by using the following query :
select * from mst_question where test_id = 1 ORDER BY RAND() LIMIT 25
This generates a random questionnaire of 25 questions for my Online Exam Application.
So far Its working good...
Now, I need to implement a feature in my application where the 25 randomly generated questions ( or whatever number - this will depend on the test id ) will always have a FIXED mix of the different types of questions available in the master question table ( mst_question ) for every randomly generated questionnaire set.
Say, if master question table is having 108 questions for a particular test id and all the three types of questions are in the db for this test , it will provide same number of different types questions for each random query !! I have written the following sql query to find out the percentage of each type of question in the master question table.
So far i have tried this and came up with this sql query :
select qtype,count(*) as qtypetotal,(select count(*) from mst_question where test_id = 1) as totalqtype,round((count(*)/(select count(*) from mst_question where test_id = 1)*100),2) as qtypepercentage from mst_question where test_id = 1 group by qtype
The output of above query is :
qtype qtypetotal totalqtype qtypepercentage
desc 24 108 22.22 %
multiple 34 108 31.48 %
single 50 108 46.30 %
I need to form a sql query which will give me 25 randomly generated questions where 22.22% of 25 questions should be desc type , 31.48 % of 25 questions should be multiple type and remaining 46.30 % of 25 questions should be single type.
I am stuck ....... Pls advise...
Thanks in advance :-)
Thanks #MikeBrant.... I have generated the dynamic sql which is definitely the way i wanted... just one issue now.... if i execute this sql query :
select qtype,round(25*(count(*)/(select count(*) from mst_question where test_id = 1))) as numquests from mst_question where test_id = 1 group by qtype
I am getting the following results :
"desc" "6"
"multiple" "8"
"single" "12"
and based on the above query i generate this dynamic query :
$dynamicsql[] = "(SELECT * FROM mst_question WHERE test_id = 1 AND qtype = '".trim($rstype->qtype)."' ORDER BY RAND() LIMIT ".$rstype->numquests.")";
$finalsql = implode(" UNION ALL ",$dynamicsql)." ORDER BY RAND()";
I want to generate a total of 25 random questions but the sum of these qtypes is 26 !!! and i am getting a question extra :-(
I would probably just use a UNION here:
(SELECT * FROM mst_question
WHERE test_id = 1 AND qtype = 'desc'
ORDER BY RAND() LIMIT X)
UNION ALL
(SELECT * FROM mst_question
WHERE test_id = 1 AND qtype = 'multiple'
ORDER BY RAND() LIMIT Y)
UNION ALL
(SELECT * FROM mst_question
WHERE test_id = 1 AND qtype = 'single'
ORDER BY RAND() LIMIT Z)
ORDER BY RAND()
You can use a query like you posed on your original question to get the values for X, Y, and Z to be used.