I have a table with 100,000 records described as:
ID primary unique int (5)
Ticket unique int (5)
user varchar (20)
Only fields populated on that table are the first two, ID and Ticket. I need to now assign a user to that ticket when requested. How can i do this? How can I find where the next null user is on the table?
Edit: Explaining Scenario as requested
Its a lottery system of sorts. The Ticket numbers have already been made and populated into the table. Now when a user signs up for a ticket, their username has to be inserted next to the next available ticket, in the user field. Im sure theres a much simpler way to do this by inserting the ticket with all the information on a new table, but this is th exact requirement as dumb as it sounds.
So how can I find out where the next null user is on the table?
What is the sorting scheme of the table ?
If the Id numbers are sequential this should work:
SELECT ID FROM TABLE WHERE user is null ORDER by ID LIMIT 1
If Id numbers are NON sequential and you are OK with using the natural sort of the table (sorted as they were entered)
SELECT ID FROM TABLE WHERE user is null LIMIT 1
Find the next NULL row by doing:
SELECT ID
FROM Ticket
WHERE user IS NULL
LIMIT 1;
When you update though you'll have to be careful you don't have a race condition with another process also getting the same ID. You could prevent this duplicate allocation problem by having a separate table holding the TicketAllocation, and giving it a unique foreign key constraint pointing back to the Ticket table.
you can also do it in a single query:
UPDATE users SET user = [username] where id =
(select min(id) from users where user is null)
This assumes ID is auto-incremented.
Start by finding the first record where the user field is null:
Select * from users where user is null order by id asc limit 1;
Then fill it in:
Update users set user = [username] where id = [id from select];
Related
I'm using mysql and php.
I'm doing a type of user drawing entry where I take a users information and store it in a mysql database. Currently the database is setup with a unique column from eliminated people from entering multiple times.
What I would like to do is allow them to re-enter after "n" other entries have been submitted. I plan to pull the last "n" entries with php and run a regex. If they aren't able to re-enter I would like to tell them what spot they are at.
Current Database:
Field Type Null Key Extra
idp int(30) NO PRI auto_increment
url varchar(250) NO UNI
name varchar(250) NO UNI
date timestamp NO on update CURRENT_TIMESTAMP
This is my current query to grab last "n" records:
SELECT url FROM mytable order by idp desc limit 50
My thought is that a second counter in my database would be the best solution that resets every "N" entries. Is this possible? I'm still bit of a novice with PHP so hoping I can find a solution I can manage.
My other concern is that my current counter increments even when someone attempts to add an entry but isn't able to because a field is not unique. Is there a way to only count when a field is actually inserted into the database?
If you give us more details we can help more. But from what I know so far, ou could do something like this:
//userInput = What the user types in
//x = select ID from users table where userInfo = userInput sort Desc Limit 1
//y = select ID from users table sort DESC Limit 1
//if y-x > 999
//enter in the database
//else
//Echo "You have to wait for ".999 - (y-n)." more contestants.";
Is there any way to stop duplicate entries only if two columns are repeating the same value.
I am using MySQL.
for example
I have one table "voting" and fields are
id
vote
user_id
message_id
In this user can enter up or down vote for a message.
I don't want the user to add multiple vote for the same message
i.e if user_id 1 votes up to message_id 1
then if the same user votes up again for same message , i don't want to allow this repeating process .
I mean is there any way to set unique constraints for fields user_id and message_id and don't allow to insert a row if user_id and message_id is repeating.
I know we can stop it using logical code using php.
I am expecting answers is there any way to do this using mysql only.?
This should work:
ALTER TABLE `table`
ADD CONSTRAINT uc_user_message UNIQUE (user_id ,message_id )
Ok so a user comes to my web application and gets points and the like for activity, sort of similar (but not as complex) as this site. They can vote, comment, submit, favorite, vote for comments, write description etc and so on.
At the moment I store a user action in a table against a date like so
Table user_actions
action_id - PK AI int
user_id - PK int
action_type - varchar(20)
date_of_action - datetime
So for example if a user comes along and leaves a comment or votes on a comment, then the rows would look something like this
action_id = 4
user_id = 25
action_type = 'new_comment'
date_of_action = '2011-11-21 14:12:12';
action_id = 4
user_id = 25
action_type = 'user_comment_vote'
date_of_action = '2011-12-01 14:12:12';
All good I hear you say, but not quite, remember that these rows would reside in the user_actions table which is a different table to the ones in which the comments and user comment votes are stored in.
So how do I know what comment links to what row in the user_actions?
Well I could just link to the unique comment_id in the comments table to a new column, called target_primary_key in the user_actions table?
Nope. Can't do that because the action could equally have been a user_comment_vote which has a composite key (double key)?
So the thought I am left with is, do I just add the primary keys in a column and comma deliminate them and let PHP parse it out?
So taking the example above, the lines below show how I would store the target primary keys
new_comment
target_primary_keys - 12 // the unique comment_id from the comments table
user_comment_vote
target_primary_keys - 22,12 // the unique comment_id from the comments table
So basically a user makes an action, the user_actions is updated and so is the specific table, but how do I link the two while still allowing for multiple keys?
Has anyone had experience with storing user activity before?
Any thoughts are welcome, no wrong answers here.
You do not need a user actions table.
To calculate the "score" you can run one query over multiple tables and multiply the count of matching comments, ratings etc. with a multiplier (25 points for a comment, 10 for a rating, ...).
To speed up your page you can store the total score in an extra table or the user table and refresh the total score with triggers if the score changes.
If you want to display the number of ratings or comments you can do the same.
Get the details from the existing tables and store the total number of comments and ratings in an extra table.
The simplest answer is to just use another table, which can contain multiple matches for any key and allow great indexing options:
create table users_to_actions (
user_id int(20) not null,
action_id int(20) not null,
action_type varchar(25) not null,
category_or_other_criteria ...
);
create index(uta_u_a) on users_to_actions(user_id, action_id);
To expand on this a bit, you would then select items by joining them with this table:
select
*
from
users_to_actions as uta join comments as c using(action_id)
where
uta.action_type = 'comment' and user_id = 25
order by
c.post_date
Or maybe a nested query depending on your needs:
select * from users where user_id in(
select
user_id
from
users_to_actions
where
uta.action_type = 'comment'
);
im having a problem with a small issue within this query
$update = mysql_query("UPDATE earnings SET userid = (SELECT ID FROM users WHERE installid is NOT NULL ORDER BY rand() LIMIT 1) WHERE userid='0'");
this query update the userid within the earning table when it value of '0'
what i need to do is to update the userid where its not found within the user table
for example
Earnings table has 5 entries where userid=10
the userid 10 is not found with in the users table and users table have those ids (1'2'3'4'5)
then update this userid which have the value 10 with any of the ids found within the users table and have the installid not nulled
I'd imagine a customer would want their earnings data, of all things, to be relevant, not completely random (if some if the data is random and you don't know which, all of the data is corrupted). That said, the query gets you where you want with
UPDATE earnings SET userid = (SELECT ID FROM users WHERE installid is NOT NULL ORDER BY rand() LIMIT 1) WHERE userid NOT IN (SELECT ID FROM users)
What I'd do instead is put a foreign key on the ID and prevent the random data being written in in the first place. I cannot see a solution where having random IDs would be better than not having those rows at all. If the IDs are not important, why have them at all?
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