I have a table that contains a Session ID, user ID, and Last Activity field.
Each time a user accesses the website, their session ID is inserted into the database.
If a Session ID is present, but User ID is set to 0, then the user is marked as a guest.
If a Session ID is present, and the User ID field is not 0, then the user is marked as a registered online users
My Question:
What's the best way to display the total users online, and split this information up in to how many are guests, and how many are registered? Can this be done with one query?
Example: There are currently xxx users online. xxx are registered, and xxx are guests.
Many Thanks,
FishSword
EDIT:
My session MySQL table contains the following fields:
sid - Stores the session ID.
user - Stores the user id of a logged in user. 0 is stored if the user is a guest.
ip - Stores the ip address of the user.
updated - stores a timestamp of when the user was last active.
Example Data:
See example data below. sud, user, ip, updated
sd456asdfas65asf465, 0, 192.168.128.33, 1315181434
v654xc654v65xc4v65z, 24, 192.168.128.65, 1315181529
dfsddas654g4sa6g4s6, 0, 192.168.128.33, 1315203155
y4g4df65gv4ff6sd54g, 69, 192.168.128.76, 1315181134
c4cs546sd654sdf654df, 42, 192.168.128.85, 1315181101
if465fsdf465sd46z65, 24, 192.168.128.65, 1315203144
dasd645as46d5a46465, 69, 192.168.128.12, 1315181134
Example 1 and 3 should only be logged once (as one guest online), as they have the same user id, and have came from the same computer/ip address.
Example 2 and 6 should only be logged once (as one member online), as they have the same user id, and have came from the same computer/ip address.
Even though example 4 and 7 have came from a different computer, user 69 should only be logged as once (one member online), as they have the same user id, and have came from the same computer/ip address.
Cheers! ;)
Make table
ID | SessID | Guest
1 | someRand | 1
2 | someRand2 | 0
And select it like
SELECT (SELECT COUNT(1) FROM sessions WHERE Guest = 1) as guests, (SELECT COUNT(1) FROM sessions WHERE Guest = 0) as users
and show it like
<?php
$result = mysql_query("SELECT (SELECT COUNT(1) FROM sessions WHERE Guest = 1) as guests, (SELECT COUNT(1) FROM sessions WHERE Guest = 0) as users");
$row = mysql_fetch_assoc($row);
echo "There are ".($row['users'] + $row['guests'])." users online, ".$row['users']." registered and ".$row['guests']." are guests";
SELECT COUNT(*) AS online,IFNULL(SUM(user_id=0),0) AS guests,IFNULL(SUM(user_id>0),0) AS registered FROM (
SELECT DISTINCT ip_address,user_id FROM sessions
) x
Create a table (recommended) or in user table where to store a last action timestamp column.
user_id | action_timestamp |
------------------------------
1 | 2011-08-15 13:02:00 |
2 | 2011-08-15 12:34:00 |
3 | 2011-08-15 11:05:00 |
Then to pull last online users for interval you make following select:
SELECT COUNT(*) FROM table AS t WHERE TIMEDIFF(NOW(), action_timestamp) < '00:15:00' /* fifteen minutes */
Now you have a count of online users in the last 15 minutes.
This will decrease overall performance (depending on the request and records), because every time the user makes a request you have to set two queries, one to insert/update record, and one for displaying the stats bellow.
You may combine the two queries into one multi-query to compensate a little bit.
Related
Let's say I have a table that stores user info with each row structured like:
(int) FileId |(int) userId | (int) DownloadHits | (varchar) UserName
Each user may have a lots of files uploaded by their names.
I want to show a list of user that have top download hits, look like :
userId UserName DownloadHits
1 Key 120
2 Bob 50
3 Zero 15
I tried SUM method but it only show the top one user.
Is there any solution for this query ?
select userid,username,
sum(downloadhits) as theDowns
from tblName
group by userid,username
order by theDowns desc
I am currently new with PHP and MySQL and I am trying to create a system for time logs (to record time in and out).
I have created a table for users where the accounts of employees are stored and have created different tables named after the different users. What I want to do is store the time in and out to the table named after the user that is logged in.
(User(currently logged in) = Employee1. The time in and out data then should be stored in the table named "Employee1".
How do I search for the right table base on the user's username with PHP?
You don't want to use a different table for every user. Have one table called employees that looks something like this:
ID | First_name | Last_name | Favorite_ice_cream
-------------------------------------------------------------------------
1 Bill Joneston Chocolate
2 Harry Smitters Sherbert
This table stores the employee's basic information. Note that the ID is unique for every employee.
Then have another table called time_logs that looks something like:
Employee_ID | Time_In | Time_Out | Date
---------------------------------------------------------------
1 8:00 5:00 2014-05-05
2 8:30 5:30 2014-05-05
Now you can just use these two tables to track employee time logs.
To get Harry Smitter's time stats for May 5th, based on his name, run a query like this:
SELECT
log.time_in,
log.time_out
FROM time_logs log
JOIN employees e ON e.id = log.employee_id
WHERE e.first_name = 'Harry'
AND e.last_name = 'Smitters'
AND log.date = '2014-05-05'
Note that, if there happens to be two 'Harry Smitters' with stats for May 5th, you will get both of their stats.
I am making a basic CMS system which allows for page edits by registered users.
I wish to store a list of users who have submitted some page content to each a specific page. In my database table for pages, I have a column called contributed, and in there I want to have all the user id’s of each user who contributed to each page, separated with a common. Looking something like this ...
Page Name | Author | Comments | Contributed
---------------------------------------------------------------
Home | 1 | 0 |1, 2, 3, 4
About | 1 | 0 |1, 3, 4, 7, 9
Contact | 2 | 0 |2, 4
Download | 8 | 0 |8
Using MySql, how can I write an update query that appends another user id to this column when a user makes a contribution instead of updating the entire row, removing the ids of those who have previously contributed?
For this, it would be best to create some sort of history table. Example:
**page_history**
id
page_id //ID of the page
user_id //ID of the user making the change
date //Date and time of the change
from //The old content
to //The changed content
Then you'd insert a new row into page_history every time a user edits a page. Note: You should read up on the concept of Database Normalization.
I might end up doing this on one level up - without any knowledge of size of your CMS:
CREATE TABLE test(pageid INT, contributed VARCHAR(1024));
INSERT INTO test(pageid, contributed) VALUES (1, "kala");
UPDATE test SET contributed = CONCAT((SELECT contributed FROM (SELECT * FROM test) as a WHERE pageid = 1),',','new_user_name') WHERE pageid = 1;
For SELECT * FROM test there is good description at
You can't specify target table for update in FROM clause
The query below selects the 'loves' on an item. (think of it as similar to facebooks 'like' system.
There are two tables in use in this select. A link table (containing itemid, userid, lovetime) and this is joined to a users table in order to retrieve the username/user profile url etc.
$lovequery = "select love.lovetime, love.userid as ID, love_users.display_name, love_users.user_url
from ".$wpdb->prefix."comment_loves love
left join ".$wpdb->prefix."users love_users on love_users.ID=love.userid
where commentid = $itemid
order by love.lovetime desc
limit 4
";
The results are limited to 4 because I simply do not need any more data. The total count is stored separately in the actual item table to reduce queries.
Once the rows are retrieved from this query I iterate through the array, cross referencing against the total 'lovecount' and build a text string formatted like so:
You, John Smith, Joe Bloggs and 4 others love this.
This works fine however it fails if the logged in user (YOU) does not have the most recent 'lovetime'
What I want to do is have the currently logged in use always at the top of the returned results even if his/her 'lovetime' is older than the 4 most recent ones so that the string always begins with 'You' if the logged in user has 'loved' this item.
The logged in user id is available in the script as $userid.
To clarify
if I have the following table (the timestamps are written as simple UK dates for legibility purposes):-
userid commentid lovetime
34 3 02/10/2011
24 3 03/10/2011
13 3 06/10/2011
65 3 14/10/2011
1* 3 10/09/2011
* with userid 1 being the logged in user id
I would only get user id's 34,24,13,65 returned in that order due to ordering by 'lovetime'
What I want is for the results to return ideally 1,34,24,65. if that proves too tricky then getting 5 total rows when the userid exists would be okay also.
I hope this is clear enough, it was rather difficult to articulate.
How would I go about modifying the query to ensure the results are as described.
Many thanks.
You can order result by condition like ORDER BY (ID = "auth_user_id") DESC
I am working on an application with PHP + MySql. In my application I have a table for users, a table for relationships (friends, following, subscribed) and a table for posts. The main actions for users are:
A user has friends
A user can make post entries
A user can see the friends entries
And finally a user can block entries viewing for specific friends
If user A is friends with user B, then user A can see all entries from user B. But user B can restrict access to only a few friends for example. Now the query is: how can I manage these permissions? I was thinking of a table that stores each user that is blocked for viewing an specific entry, but this would't be a good idea once a single user can have several friends. So, how can I solve this? Can someone show me how to start? Maybe the right terms for searching on Google or a link for something similar.
You are on the right track. You are going to want to use linked tables. You would start with a table users. Each user has an id. Then create a table users_friends. This table would consist of two ids, user_id and friend_id. The last table would be users_restricted which would also consist of two ids, user_id and restricted_id.
For example
users
user_id name
1 user1
2 user2
3 user3
users_friends
friend1_id friend2_id
1 2
2 3
This says user 1 and 2 are friends and users 2 and 3 are friends. (This assumes that if user 1 is friends with user 2 then user 2 is also friends with user 1)
users_restricted
user_id restricted_id
1 2
Now even though user 1 and user 2 are friends, user 2 is in the restricted list meaning don't allow user 2 to view user 1's entries.
You can see that tables are linked via ids and all the ids come from the users table. This can be expanded to relate to entries as well. Just refer to entries by their id.
To have users blocked for specific entries you would have the following tables.
entries
entry_id user_id ... other columns holding entry information
1 1
2 1
3 2
4 2
Now user 1 has made 2 entries (entry 1 and entry 2) and user 2 has made 2 entries (entry 3 and entry 4). Another table would hold the restrictions.
entries_restricted
entry_id restricted_user_id
1 2
This would say user 2 cannot view entry 1.
To get the entries visible to user 2 your statement would look something like this.
SELECT e.*, er.entry_id FROM entries e JOIN entries_restricted er ON e.entry_id=er.entry_id WHERE er.restricted_user_id != 2;
The statement selects all the entry information excluding entries restricted to user 2.
You can start using following tables.
The first table is users table (as Jason.Wolfsmith suggested)
users
u_user_id u_name
1 user1
2 user2
3 user3
The second table can be like this.
friends_permissions
f_user_id f_friend_id permission entries
1 2 1 entry1
2 3 0
1 3 1 entry3
This table will contain permission and name of entries that should be allow for view. 1 - restrict some entries; 0 - allow all.
In the column permission data type might be set as SET('1','0') and data type in entries NULL.
Thus, user1 don't allow to view entry1 to user2. (entry1 and entry3 are from entries table).