Talbe row value (MySql) - php

I have some difficulties with a table.
I got a site that users can't send in 6 different answer to lessons.
After the user has done that, he can correct 3 others answers.
When the user have delivered 1 and corrected 3 of same modulid he will have the modulid approved.
The table I have contains these columns:
username, modulid, correctedby, answer, result
It the correcting part that I'm having problems with.If one have corrected one, it will get row value 1, and if 2 user has corrected it, value changes to 2, etc..
Can I somehow set a table row to have a default value NULL and contain the value to be from 1 to 3?
Then some one try to add something the 4 times, i want to output a message like " it full"(and you wont get it as option for searching for modulid to correct)
Can i write like this:
$sql = "SELECT modulid=1 FROM tablename WHERE correctedby=1-3 NULL ORDER BY RAND() LIMIT 1";

Try this:
SELECT modulid FROM tablename
WHERE modulid = 1
AND (correctedby IN (1,2,3) OR correctedby IS NULL)
ORDER BY RAND() LIMIT 1
But your result will either be:
modulid
=======
1
or no rows returned.
You should control / filter the input before inserting into database (e.g. check if the database is "full", based on your designed criteria)

Related

Select random row where condition apply effectvely

I have a table of names with structure likes this :
id int(11) -Auto Increment PK
name varchar(20)
gender varchar(10)
taken tinyint - bool value
I want to get a random name of a single row where gender is say male and taken is false. How can I do that without slowing down ?
What comes to mind is, SELECT all the rows where gender = male and taken = false. Then use php's rand(1, total_rows) and use the name from that randomly generated record number for the array of results.
Or I can use, but RAND() is going to slow down the process (taken from other questions on stackoverflow)
SELECT * FROM xyz WHERE (`long`='0' AND lat='0') ORDER BY RAND() LIMIT 1
You can take the following approach:
select the id list that meet your criteria, like SELECT id FROM table WHERE name=...
choose an id randomly with php
fetch whole data with that id, like SELECT * FROM table WHERE id=<id>
This approach would maximize the query cache in MySQL. The query in step 3 has a great chance of hitting the same id, in which case query cache can accelerate database access. Further more, if caching like memcached or redis is used in the future, step 3 can also be taken care of by them, without even going to db.

Selecting unique combinations only once

I got a message system with a table like this
ID AID FID MESSAGE
1 1 2 Hi
2 2 1 Hi, how are you?
3 3 1 Hello One, what's up?
4 1 2 I'm fine, how about you?
ID is the unique Message-ID, AID the ID of the transmitter and FID the ID of the receiver of the message. Message is the message itself.
I want to select all unique combinations with the highest ID, but only once, so the output looks like this:
ID AID FID MESSAGE
3 3 1 Hello One, what's up?
4 1 2 I'm fine, how about you?
The problem is that I can't select properly as AID=2 and FID=1 is as unique as FID=1 and AID=2, but it's in fact the same conversation.
Any suggestions would be very appreciated!
EDIT: The ID of the user currently logged in is $_SESSION["said"]
EDIT 2: The message system should look something like this, displaying the last message sent in a conversation (just like on facebook).
http://i.stack.imgur.com/Jmvfr.jpg
here is query:
select * from table
where ID in (
select max(id) as maxid
from table
group by LEAST(aid, fid), GREATEST(aid, fid)
)
if you want to select last message only from/to $_SESSION["said"], you can use:
$query = "select * from table
where ID in (
select max(id) as maxid
from table
where aid = ".$_SESSION["said"]." or fid = ".$_SESSION["said"]."
group by LEAST(aid, fid), GREATEST(aid, fid)
)";
it will give you list of all latest messages sent to/from this user
Might have to modify it depending on your RDBMS (MySQL vs. Microsoft SQL Server, etc.), but the following code should get you headed in the right direction... You'll probably need to modify the string concatenation to use some sort of cast or something, but, like I said, it's RDBMS-dependent.
Pseudocode:
select *
from have
where id in
(
select max(id) as topid
from have
group by case when aid<fid then aid+'|'+fid else fid+'|'+aid end
)

SQL query using replace a value in one table by randomly selecting a value in another table

I have a table with an value that I would like to be updated periodically with a cron job. However, I need to update the value by replacing it with a value from a different table. The issue is that I would like the replacement value to be chosen randomly.
For example, Table 1 has
ID Email
=================
1 bobatumail
Table 2 has:
ID Email
================
1 bobatumail
2 joeatumail
3 peteatumail
4 biffatumail
5 wilneratumail
6 wilsonatumail
I would like the query to replace bobatumail in Table 1 with any of the other values in Table 2 as long as it is random. It could even be the same value as in Table 1.
Any idea how to do this?
In MySQL you could use the REPLACE statement:
REPLACE INTO table1 (ID, Email)
SELECT 1, table2.Email FROM table2 ORDER BY RAND() LIMIT 1;
The "1" in the second line represents the id of the entry while the second part returns a random value out of table2. Yes, there are solutions using the UPDATE statement (JOIN and ANSI) but its always tricky and you usually have to turn off safe update mode.
http://dev.mysql.com/doc/refman/5.5/en/mysql-command-options.html#option_mysql_safe-updates
Please note that REPLACE first deletes the old entry and then reinserts the new one.
http://dev.mysql.com/doc/refman/5.5/en/replace.html

Check last entry before inserting into DB

Can someone give me a quick hint on how I can achieve the following:
I have a table with 3 rows: id , value1 and user.
let's say there's 1 entry in the DB with the following data:
1, test, user1
Now when I submit my form and before the next thing gets actually inserted, I want to check the value of user of the last entry in the DB and change the next entry to either user1 (if the last one is user2) or user2 (if the last one is user1)
Edit:
I think I explained it a bit stupid.
Basically I want some kind of Zebra striping for the row user if that makes any more sense :-)
It can be even easier:
SELECT user FROM table ORDER BY id DESC LIMIT 1
Assuming that id is an AI field.
EDIT: adding some PHP code:
$getLastUser = mysql_query("SELECT user FROM table ORDER BY id DESC LIMIT 1");
$LastUser = mysql_fetch_array($getLastUser);
$newUser = ($LastUser['user'] == "user1") ? "user2" : "user1";
//insert $newUser to the 'user' field.
You can proceed by executing a query like
SELECT user FROM table WHERE ID IN(SELECT MAX(ID) FROM table)
and then using that user value to determine what the next user value would be.
To avoid concurrency issues, do it all as one statement:
INSERT INTO your_table (value1, user)
VALUES ('your_value', (CASE (SELECT user FROM your_table ORDER BY id DESC LIMIT 1) WHEN 'user1' THEN 'user2' WHEN 'user2' THEN 'user1' END))
Looks like you need your Zebra striping at the output, not insert time.

PHP, select a random row from a mysql table which haven't been selected yet!

Ok, I have 3 tables;
'bu_blogs' contains blogs which have a unique blog_id.
'bu_sites' contains sites which have a unique site_id.
'bu_blogs_done' contains id, blog_id and site_id. A new row is added to this table every time a site_id is submitted to a blog_id.
What I want to do is SELECT 2 random rows from 'bu_blogs' where a field in 'bu_blogs_done' for the particular blog_id and site_id does not exist, i.e it haven't been submitted to that blog_id yet.
Thanks
Stian
If your table isn't too big (e.g. approx 100 rows), you can use something like this simple example for the random part:
SELECT * FROM bu_blogs ORDER BY RAND() LIMIT 2
Then it's just a case of adding a WHERE clause to filter out the ones that exist in bu_blogs_done.

Categories