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.
Related
So, I have a table A that each time a user sends an image, a record is created storing the time it was uploaded, the username of the user and the image number out of all the images uploaded over time.
I need to make a second table B that will store the amount of images uploaded per user and the user name. I need this table B to be updated when a new entry is generated in A.
I found that a trigger function can be created, nevertheless I'm having a rough time finding an example that will suit my needs.
Does anyone know a way of doin what I want?
Just update b table with a select count of total inserted records on a from current user NEW.userid (userid is your column name or whatever name you have there, and NEW is a fixed mySql reference for the current values to be inserted):
CREATE TRIGGER img_sum AFTER INSERT ON a
FOR EACH ROW SET b.total = (SELECT COUNT(*) FROM a WHERE a.userid=NEW.userid)
WHERE b.userid = NEW.userid;
From what you have described i don't think you need a second table. You can just count the number of time a user name has occurred, and you will get the number of images that user has uploaded.
You can get the count doing something like that
SELECT COUNT(DISTINCT username) FROM table_name;
If you still need to create 2 tables, you might want to take a look at procedures and how they work.
Let's say we have 3 tables for this case:
- users(id, username, email ....),
- user_images(id, userId, image_num, date_uploaded)
- user_images_count(id, user_name, images_count)
The user_images_count is initially empty. We have to fill it up by such query:
INSERT into user_images_count(user_name, images_count)
SELECT (select username from users where ui.userId = id) as username, count(userId) as counter FROM `user_images` ui group by ui.userId;
Then, we must immediately create the trigger that will process every INSERT operation into user_images table.
CREATE TRIGGER `count_user_images` AFTER INSERT ON `user_images`
FOR EACH ROW begin
declare u_name tinytext default "";
set u_name = (select username from users where id = NEW.userId limit 1);
if(u_name != "") then
update user_images_count set images_count = images_count + 1 where user_name = u_name;
end if;
end
This two queries (user_images_count fulfillment and trigger creation must be performed in one transaction, one by one).
I've created similar triggers on my local databases. They work pretty good. )))
My professor wants us to create a web-based comment system wherein a user can send up to 3 comments, if the user decides to create another one when he already has 3 comments named after him on the database, the program should delete the oldest one and save the new one.
What I thought about was to fetch the rows named after the user and if it is greater or equal to 4, I should delete the row where username = session user and insert the new record. Although this was just in theory, is this the best way to go about this? Do you guys have any other suggestions? How exactly do I pick the rows to remove? Do I base it off the highest comment_id?
Read: Leave only first 50 records in SQL database and delete the rest
So basically do this:
Create an Auto Increment Id with the comments.
Then:
DELETE FROM comments
WHERE
id NOT IN (
SELECT * FROM (
SELECT id
FROM comments
ORDER BY date
desc LIMIT 3) s
)
Do not delete the rows in the database, just do a limit 0,4 on your select query
with a order by on a create date
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)
I have the database where i save my records. The records was saved as
ID, name
example
Nick
Name
Username
Now when i delete the record with id 2. in my database it remains as
1. Nick
3. Username
I want that when i delete one record from database other id's automatic decrement for one value so i get.
1. Nick
2. Username
Do you understand my question. Sry for bad english
Button delete code
if(isset($_POST['tipkaobrisi'])) // pritisnuta tipka obrisi
{
$obrisankorisnik = $_POST['obrisi'];
if ( $obrisankorisnik == '' )echo "<div align='center'>Unesite korisnika kojeg zelite obrisati!</div>";
else
{
mysql_query("DELETE FROM Korisnici WHERE Korisnik ='$obrisankorisnik'");
echo "<div align='center'>Korisnik obrisan<br><br></div>";
}
}
That is not the intention of most ID columns. However, you can mimick this functionality by modifying the statement you use to access those records.
E.g. rather than using the ID value, use the following
select #rownum:=#rownum+1 as ID, name from users, (SELECT #rownum:=0) r order by id;
It will give each record returned a number, with no gaps. Depending on what you want this for, that may be enough. If you would like to treat this new ID value as the ID value, create a view and access your elements based on that, like so:
CREATE VIEW users_view as select #rownum:=#rownum+1 as ID, name from users, (SELECT #rownum:=0) r order by id;
at which point you can SELECT * FROM users_view WHERE ID = $id and have it work as usual. So long as you never insert a new record that is not auto incremented, this scheme should work.
Keep in mind that deleting anybody changes a bunch of IDs, so it's not recommended.
After listening other programer's advice's. I decide that i don't want to edit my ID's.
Thanks to all for participating.
I have a table with three fields - userID, couponID, last_couponID.
When the user accesses a coupon, I run this query:
mysql_query("INSERT INTO users_coupons (userID, couponID) VALUES ('$recordUserID', '$recordCoupID')");
Further, I have another query that should insert the last couponID into the field last_couponID, by polling the database table and finding the most recent result for the current userID.
I believe it is as such:
SELECT couponID FROM users_coupons ORDER BY userID LIMIT 1
Am I correct? Or should I use a different query?
Like this:
userID couponID
1 3
1 13
1 23
2 5
2 3
So if I wanted userID 2's latest coupon, it'd be '3', and for userID 1, it'd be '23'. I just want the last entry in the database table where the userID matches a value I provide.
I would just add a primary key (autoincrementing) to the users_coupons table.
When you want the latest coupon of a user,SELECT couponID FROM users_coupons WHERE userID = ? ORDER BY id DESC LIMIT 1
Assuming that couponID is numeric, and the last couponID for a certain userId is the greatest (as a number), you can do:
SELECT MAX(couponID) AS lastCouponId FROM users_coupons WHERE userId = <put here the user id>
EDIT: since you've edited your question, I edit my answer.
You have to add an auto-increment primary key, otherwise you can't know exactly which entry is the last one. When I answered, I supposed the last coupon for a certain userId was the one with the greatest couponId. Are you sure you can't just make things work this way?
Something along the lines of...
SELECT couponID
FROM users_coupons
WHERE userID = <current user id>
ORDER BY <primary key of user_coupons table if it's an identity column> DESC
LIMIT 1
...is more appropriate. Your query as it stands doesn't do anything with the 'current' user ID.
If you are actually after the highest couponID then SELECT MAX(couponID)... as suggested by Giacomo is a good idea - coupled with a check for the UserID matching the current user ID.
#Giacomo's answer is valid if you are incrementing the CouponID reliably as an identifier. If you have merged in data or are adjusting this value any other way then it may not be correct.
In theory, if you consider CouponID to be a surrogate key then you cannot use it to explicitly determine insert order. If you intend for it to be used for the purpose of insert order then you also need to make sure your supporting code and DB maintenance plans promote this use.
I contend that the "correct" method is to also store a DateTime