i try to development exam management system. I do not want same
question or same id not showing second time or other any time exam a
user. How can this condition be given?
my function is:
public function qustionShow($question, $limit=4){
$show = $this->conn->query("select * from question where cat_id ='$question' ORDER BY RAND() LIMIT $limit");
while ($row=$show->fetch_array(MYSQLI_ASSOC)){
$this->qus[]=$row;
}
return $this->qus;
}
You would need to keep track of which questions have already been asked. you can save the question id's to the Session if it's you don't want the questions to be selected again only for the session.
you could initialize an array to the session
$_SESSION['questions_asked'] = array();
and then once a question is asked you would
array_push([THE QUESTION ID], $_SESSION['questions_asked']);
of course you need to replace [THE QUESTION ID] with the sql id for whatever question was asked
keep in mind you would need to modify your query to account for anything saved in the session.
If you don't want them to ever be shown again you would need to record which questions a user has seen and would need to store that persistently in the database probably.
possibly you can have a table to store those in for each user
user_question_asked
with at least these 2 columns
[user_id][question_id]
so each time a question is asked you insert the current user id and question id
then your query could be
SELECT * FROM question where cat_id ='$question' AND [QUESTION_ID] NOT IN
(SELECT question_id from user_question_asked where user_id [CURRENT USER's ID]
) ORDER BY RAND() LIMIT $limit;`
Hope that helps, I'm not sure what your table / column structure is, but those are a couple suggestions I have for addressing this problem.
Related
Please I need help with this problem I'm facing. I'm building an examination system and I'm using the Rand() function to select questions from the "question" table. The user's answers are also saved in the "user_answer" table.
Now my problem is a question sometimes gets selected twice or thrice so I need a query that will check that if a question has already been answered in the "user_answer" table, it should reselect another question from the "question" table.
You cannot exclude with Rand() directly.
If you query from a database, you could add something like
select *
from question q
left join user_answer ua on ua.question_id = q.id
where ua.id is null
group by q.id
This will try to connect to an answer (ANY answer, you probably want to add some user selection into that), and only give back the questions where it FAILS (ua.id is null) to do so.
If you cannot do it by query and have it it all in some PHP array, what you could do is keep track of the available question ID's in an array. Each time you pick a question random, you remove that item (value!) from the array, and reindex the array (keeping the values, which are the question ID's, and ordering the keys from 0 to the number of questions - 1).
That way you can do a rand(0, count($questionIds)) again to pick the next one.
Another way would be to use a loop, and continue as long as the picked question is already in the used questions array.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
i have database tables for Posts and comments.
i want to allow users to put a like or dislike for each comments and posts.
so..i have few ideas of doing this. please tell me either i am correct or not.
create two additional columns in comments table.
likes | liked_uids
if a person clicks on like button then add +1 for the current value in likes field, else add -1 for current value.
and add user's id to liked_uids field as a sting separated by "-" dashes.
then next time i can get that string to an array and check that,
either current user id has recorded or not. if user id is, then can decide that user have participated for liking.
but i have little problem on this structure, that what will if more than one user going to like at once for a post ? then i may lose some data from liked_uids string (one last uid).
so please tell me what is the correct way of doing this?
You can create like this->
id type ('comment/like') uid comment post_id
1 comment 1 good post 100
2 like 2 null 101
3 like 1 null 102
4 comment 3 bad post 104
It is not recommended to store like count.If you want to count the likes for a particular post:
select count(*) from tableName where post_id = 100
Storing user id separted by any delimiter will land you on problems, Hence not recommended. It will be tidies job to update or retrieve if your store user id using delimiter.
If you want to see if particular user is liked a particular post or not, use below query:
select count(*) from tableName where post_id = 100 AND uid =1
One way is to use a separate Likes table with columns Likes, DisLikes, Likes_UID, DisLikes_UID and mapping table for comments and likes ex: Comments_Likes and posts and likes Posts_Likes
I'm typing way too slow on my mobile ^^ Everything already answered.
I never did anything that is similar, but I wouldn't add the two columns in the comment table. I would rather create a new table like "votes" and it would have following columns.
comment_ref | like | user_ref
Every time someone likes a comment you insert a new line there. You could also make the combination comment_ref and user_ref as a key, so you can't insert it twice.
In the end you would just make a query as such to get the votes of a single comment.
SELECT COUNT(*) FROM votes WHERE comment_ref = 123
I asked random question to student & stored his answers using his session id into mysql & than extracted the same way.
I used Order By RAND() function in my query while asking the question
$query = "SELECT * FROM question ORDER BY RAND() LIMIT 0,1";
But Now I Want to Store answers in an arranged sequence for such purpose i can use Q_ID but i don't want to show q_id to user. So how can i store q_id into another table without showing it to user.
Secondly i want to show correct answers to my students too.
but i really don't know how to tackle these thing :(
query for storing answers
$order= "INSERT INTO radio (Option1,Option2,Option3,user) VALUES ('".$Option['Option1']."','".$Option['Option2']."','".$Option['Option3']."','".session_id()."')";
Query For Extracting Data From mysql
$qry=mysql_query("SELECT * FROM radio where user='".session_id()."'", $con);
Without your actual database schema/more information it is difficult to give you the best advice possible.
Add a field to the table radio so that it looks something like this:
RADIO (*user*, *questionId*, Option1, Option2, Option3)
(due to stack overflow formatting stars represent the primary key(s))
where questionID is a foreign key that references QUESTION(id). If you don't have an id field in your question table add that too.
Then when you display the question to the user, save the question ID as a hidden input field inside the tag like so:
<input type='hidden' name='questionId' value='".$data['id']."' />
When the form is submitted you will have the question ID available in your $_POST array at $_POST['questionId']
Then you can modify your INSERT query to insert the question ID as well and simply not display it when you display the data later.
--
As for displaying the correct answers to the students, you will need to store the correct answer in your table somehow. One way would be to add a field to your question table indicating which of the options is the correct answer, I.E. a TINYINT(1) which will contain a 1, 2, or 3 depending on which answer is correct. You can then use that to generate a page with the correct answer to the question.
I have an application (More likely a quiz app) where i have saved all my 1000 quizzes in MySQL database, I want to retrieve a random question from this table when a user request one, I can easily do it using the RAND() function in MySQL.. my problem is , I don't want to give the same question two or more times to a user, how can i keep a record of retrieved questions? Do I have to create tables for each and every users? won't that increase the load time?? please help me, any help would be a big favor ..
-regards
If you want it for a short time, use the user's $_SESSION for that.
If you need the long term ( say tomorrow, not to ask the same questions) - you'll have to create additional table for usersToQuestions, where you'll store the user id and the questions the user had been already asked.
Retrieving a question in both cases would require a simple IN condition:
SELECT * FROM questions
WHERE id not IN ('implode(",", $_SESSION["asked"])')
SELECT * FROM questions
WHERE id not IN (
SELECT question_id FROM questions2users WHERE userid = 123
)
my problem is , I don't want to give the same question two or more times to a user,
how can i keep a record of retrieved questions? Do I have to create tables for each
and every users? won't that increase the load time?
Yes, but possibly not so much.
You keep a single extra table with userId, questionId and insert there the questions already asked to the various users.
When you ask question 123 to user 456, you run a single INSERT
INSERT INTO askedQuestions (userId, questionId) VALUES (456, 123);
Then you extract questions from questions with a LEFT JOIN
SELECT questions.* FROM questions
LEFT JOIN askedQuestions ON (questions.id = askedQuestions.questionId AND askedQuestions.userId = {$_SESSION['userId']} )
WHERE askedQuestions.userId IS NULL
ORDER BY RAND() LIMIT 1;
if you keep askedQuestions indexed on (userId, questionId), joining will be very efficient.
Notes on RAND()
Selecting on a table like this should not done with ORDER BY RAND(), which will retrieve all the rows in the table before outputting one of them. Normally you would choose a questionId at random, and select the question with that questionId, and that would be waaaay faster. But here, you have no guarantee that the question has not been already asked to that user, and the faster query might fail.
When most questions are still free to ask, you can use
WHERE questions.questionId IN ( RAND(N), RAND(N), RAND(N), ... )
AND askedQuestions.userId IS NULL LIMIT 1
where N is the number of questions. Chances are that at least one of the random numbers you extract will still be free. The IN will decrease performances, and you will have to strike a balance with the number of RANDs. When questions are almost all asked, chances of a match decrease, and your query might return nothing even with many RANDs (also because RANDs will start yielding duplicate IDs, in what is known as the Birthday Paradox).
One way to achieve the best of both worlds could be to fix a maximum number of attempts, say, three (or better still, based on the number of questions left over).
For X times you generate (in PHP) a set of Y random ids betweeen 1 and 1000, and try to retrieve (userId, questionId) from askedQuestions. The table is thin and indexed, so this is really fast. If you fail, then the extracted questionId is random and free, and you can run
SELECT * FROM questions WHERE id = {$tuple['questionId']};
which is also very fast. If you succeed X times, i.e., for X times, all Y random questionIds are registered as being already asked, then you run the full query. Most users will be served almost instantly (two very quick queries), and only a few really dedicated users will require more processing. You might want to set some kind of alerting to warn you of users running out of questions.
One solution is to add an ID column in the question table and when you serve it to a user you check that ID with the list of questions that you served the user.
You can use in memory data structure like List to keep track of the questions that are served to a particular user. This way, you only need array of Lists instead of tables to get the job done.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I wonder how to do this
I mean the "You and 19,389 others" How do you identify YOU from others. If a user is logged in and like a status or favorite a status or something like facebook. I wanna catch the "you" part. But I don't seemed to understand the logic behind it.
I'm using php, and jquery. How do you sort this out in sql? or is it really sql? how do you define the user from others?
If I'm doing it the wrong way or asking it the wrong way, please tell me the right way and the answer guys I badly need your help.
With only one query you can do like this:
SELECT COUNT(user_id) AS everybody, SUM(user_id = "your_user_id") AS you FROM fb_likes WHERE post_id = 4;
Then if you is bigger than zero print (in fact it must be 0 or 1 only):
You and [everybody - you] others like this.
Else
[everybody] like this.
First of all, when you click on "Like" there's an entry going inside a database assigned to the post. So let's say the post has ID 1234567890 so you going to see something like that inside your database table :
PostID UserID
1234567890 54543534
1234567890 75231415
1234567890 78653421
1234567890 99653221
// Query example
SELECT COUNT(*) FROM LikeTable WHERE PostID = 1234567890
// Return 4
First of all you count all like, there's 4 here.
After, you check if the UserID of the current logged user is in the database.
Yes. He liked.
No, he didn't liked.
Let's say we are user 54543534. I am in the database so I liked the post.
// Query example
SELECT PostID FROM LikeTable WHERE PostID = 1234567890 AND UserID = 54543534 LIMIT 1
// Return 1
Let's say we are user 8748977777. I am NOT in the database so I didn't liked the post.
// Query example
SELECT PostID FROM LikeTable WHERE PostID = 1234567890 AND UserID = 8748977777 LIMIT 1
// Return 0
So I say the IF/ELSE statement would be :
IF I liked
You and COUNT - 1 others like this.
ELSE
COUNT like this. Click to like.
EDIT :
I think something like that will make the job :
SELECT COUNT(PostID) AS All, SUM(UserID = X) AS Liked FROM LikedTable WHERE PostID = X
Query for others:
SELECT COUNT(userid) FROM likeTable WHERE postid = $postid
Query for you:
SELECT COUNT(userid) FROM likeTable WHERE postid = $postid AND userid = $_SESSION['userid']
Then do:
if ($youCount == 1) {
echo "Liked by you and " . $othersCount - 1 . " others";
}
else {
echo "Liked by $othersCount people";
}
I don't know much about optimal database schemas, but the way I see this is that every single like in Facebook terms is a node on FB's social object graph. Which probably means that every single like is an individual database record on some table. To count the number of likes, you just do a COUNT on like records associated with a post.
Now if that's the case, then it's trivial to include some identifying information on the like record on who performed it. Top-of-head, it would be an FK on a user's PK.
So if you're logged in on Facebook, it knows who you are and what your associated user ID is. For every post that it aggregates the likes to, it can counter-check your user ID to the user ID FKs on the likes, and determine which of those posts you've actually liked. Hence, it can conditionally display either You and 14,000 others like this or 14,001 like this.
Struggling to understand the question but I think you might be trying to do too much in one go.
Either Run two queries, one to check if 'you' (your session id etc.) are in the table that records this or pull the whole lot and use in_array or something similar to see if 'you' are in the list.