How do I count unique visits base on date - php

I have a reports table where i count hits by just using the code below.
// Get hits
$hits_query = mysql_query("SELECT COUNT(*) AS `count` FROM `reports` WHERE `stuff_id` = ".$row->id."");
$fetch_hits = mysql_fetch_array($hits_query);
$hits = $fetch_hits['count'];
That code works great and does exactly what i want but what i want now is how to get unique hits?
In my reports table i store every access so theres multiple log for each user base on the stuff_id . In my reports table I store the date as 01-23-2013 on each report, along with the user ip and stuffed which every 24 hours change from 2 to 1.

You need a field that uniquely identifies the user. I am going to assume for my example that it is user_ip. Change this:
$hits_query = mysql_query("SELECT COUNT(*) AS `count` FROM `reports` WHERE `stuff_id` = ".$row->id."");
To this:
$hits_query = mysql_query("SELECT COUNT(DISTINCT `user_ip`) AS `count` FROM `reports` WHERE `stuff_id` = ".$row->id."");
NOTE: mysql library will be deprecated as of PHP 5.5 and removed in future versions of PHP. It would be a good idea to start planning a migration away from it.

you can do this:
$hits_query = mysql_query("SELECT COUNT(DISTINCT `user_ip`) AS `count` FROM `reports` WHERE `stuff_id` = ".$row->id."");
Or if you want a unique response, you can do this:
$user-IP = "Put here the ip adress of the user that you want";
$hits_query = mysql_query("SELECT COUNT(*) AS `count` FROM `reports` WHERE `user_ip` = ".$user-IP."");

Related

Fetching data with Group by, How to select the latest or greatest id? (PHP to MySQL)

I wanted to fetch data from MySQL with PHP when a user inputs something. I have this code.
$query = "SELECT * FROM mealplans WHERE plantitle LIKE '%$inputText%' AND `STATUS` = 1 OR plantitle LIKE '%$inputText%' AND userid = '$userid' GROUP BY plantitle, userid";
$result = mysqli_query($con, $query);
It works fine however, it fetches the oldest or first data from the group. How do I select the newest data?
I've search and found possible solutions by using FROM, JOIN, IN, etc. However, I do not know how to use them since I only know the basics. Hopefully someone could explain one solution for me.
There is a simple solution that you can do.
You can order your data to DESC order. I'm sure that you have an id(primary key) in your table.You just have to order all your datas' to DESC order of ids .So that your last inserted data set will be the one to be fetched since it's on the top.
change your query to: (add your primary key(in the following query i have added it as id) in the ORDER BY syntax)
$query = "SELECT * FROM mealplans WHERE plantitle LIKE '%$inputText%' AND `STATUS` = 1 OR plantitle LIKE '%$inputText%' AND userid = '$userid' GROUP BY plantitle, userid ORDER BY `ID` DESC"
Just add a condition in your query which only retrieves the row having the greatest id.
Find out the id first and then you can use the same query for that id:
SELECT MAX(id) FROM mealplans WHERE plantitle LIKE '%$inputText%' AND `STATUS` = 1 OR plantitle LIKE '%$inputText%' AND userid = '$userid' GROUP BY plantitle, userid
After getting the id and storing it in a variable (say $temp):
SELECT * from mealplans where `id` = $temp

Add MySQL Count Column to PHP/HTML Table

I'm developing a website using HTML, PHP and MySQL to access a database. On one page I present a table with data from that database. This is some of the code I'm using:
$sql1 = "SELECT * FROM MyTable ORDER BY ID ASC";
$rs1 = mysqli_query($link,$sql1);
(...)
while($row1 = mysqli_fetch_assoc($rs1)) {
echo "<tr><td>".$row1['ID']."</td><td>".$row1['Field1']."</td><td></td><td>".$row1['Field2']."</td><td>".$row1['Field3']."</td></tr>\n" ;
}
Notice the empty <td></td>? That's because I want to have there the number of time a given ID appears on two other tables (there are foreign keys involved, obviously). I have sorted out the code I need for that:
$sql2 = "SELECT (SELECT COUNT(*) FROM MyTable2 WHERE ID2=$row1['ID'])+(SELECT COUNT(*) FROM MyTable3 WHERE ID2=$row1['ID']) AS total";
However, I'm struggling with figuring out a way to add this result to the other table. Any help?
try with this.. it inserts the total to an table after selecting the count.
"INSERT INTO total_table (total)
SELECT (SELECT COUNT(*) FROM MyTable2 WHERE ID2=$row1['ID'])+(SELECT COUNT(*) FROM MyTable3 WHERE ID2=$row1['ID']) AS total
WHERE cid = 2"

Increase speed of PHP and MySQL webservice

I have created a web service using php and mysql to insert and return data for my app. One of the main complaints from users is the response is too slow, which I agree, as it takes anywhere from 5-10 seconds to complete task. Originally thought it was a hosting performance issue, but has not made a difference (godaddy versus AWS).
Looking at the SQL code in my php files, I think that is the issue. I'm looking to re-write to increase speed. I believe the issue is I use timestamps, and to return I always look for the max(timestamp).
Here is my input SQL statement:
$insert = mysql_query("INSERT INTO meals (user, date, meal, timeStamp, food) VALUES ('$user','$date','$meal','$timeStamp','$food')");
Here is my return SQL statement:
$query = mysql_query ("SELECT * FROM meals WHERE user = '$user' AND date = '$date' AND meal = '$meal' AND timeStamp = (SELECT MAX(`timeStamp`)FROM meals WHERE user = '$user' AND date = '$date' AND meal = '$meal')");
Would I be better off using an UPDATE or similar instead of using timestamps? Any other recommendations?
This is your query:
SELECT *
FROM meals
WHERE user = '$user' AND date = '$date' AND meal = '$meal' AND
timeStamp = (SELECT MAX(`timeStamp`)
FROM meals
WHERE user = '$user' AND date = '$date' AND meal = '$meal'
);
Assuming that you want only one row, the first simplification is:
SELECT *
FROM meals
WHERE user = '$user' AND date = '$date' AND meal = '$meal'
ORDER BY timestamp desc
LIMIT 1;
Next, indexes will help this query. In fact, an index on meals(user, date, meal, timestamp) would work for both the where and the order by. That should improve performance.

SQL for sorting out next/previous picture in gallery

I'm working on the photo section of my website, but more precisely on the next/previous link with sorting options.
There are two different option for sorting that exist, first there is a filter (Latest, Trending, Favorite, User etc.) and secondly a sorting option for some of the previous filters (date, views, ratings etc.)
I am having trouble finding a good solution for easily retrieving the next/previous picture for my slideshow.
This is the little bit of SQL I have for getting the next picture for a filter:latest
if ($filter == "latest") {
$sql = "SELECT *
FROM photos
WHERE status = 0 AND id < ".$id."
ORDER BY id DESC
LIMIT 1
";
$result = $db->sql_query($sql);
$sql2 ="SELECT *
FROM photos
WHERE id = (SELECT MAX(id) FROM photos WHERE status = '0')
ORDER BY id DESC
LIMIT 1
";
}
I am wondering if there is an easier way to implement this in my project ? maybe a php class exists to do something like this ?
I feel like I'm going to spend a long time getting all these SQL queries to work properly if I have to do it all like this.
Edit
This is the layout of my photos table
`id` -> unique ID, autoincremented
`title`
`img_name` -> contains the image file name
`date_created` -> when the picture was uploaded
`uploader` -> id of the user that uploaded
`views` -> number of views the picture has
`up_votes` -> votes used to calculate the Wilson score interval
`down_votes`
`net_votes` -> up vote minus down votes
There are other tables like one that links user with friends they have, it is called users_friends
`user_id` -> contains id of the user that added the friend
`friend_user_id` -> contains id of the friend in question
With these two tables I am able to get all the pictures posted by the friend of a user using this sql query :
SELECT *
FROM photos
WHERE uploader IN
(
SELECT friend_user_id
FROM users_friends
WHERE user_id = ':user_id'
)
ORDER BY id DESC
I then have two queries to get the link to the next picture and 2 other queries for the previous one. I have two because one is for when you get at the end of the database to go back to the other end and the other one is for all the other queries. And they look something like this (I'm only posting the next button here)
$sql = "SELECT *
FROM photos
WHERE status = 0 AND id < ".$id." AND Uploader IN (SELECT friend_user_id FROM users_friends WHERE user_id = ".$logedInUser['User_ID'].")
ORDER BY id DESC
LIMIT 1
";
$sql2 ="SELECT *
FROM photos
WHERE id = (SELECT MAX(id) FROM photos WHERE status = '0' AND Uploader IN (SELECT friend_user_id FROM users_friends WHERE user_id = ".$logedInUser['User_ID']."))
ORDER BY id DESC
LIMIT 1
";
$result = $db->sql_query($sql);
if (mysql_num_rows($result)==1) {
$row = $db->sql_fetchrow($result);
return "/photo/".$row["id"]."/".urlFriendly($row["Title"])."/".$filter.$sort;
}
else
{
$result = $db->sql_query($sql2);
$row = $db->sql_fetchrow($result);
return "/photo/".$row["id"]."/".urlFriendly($row["Title"])."/".$filter.sort;
}
I feel like there is a lot of stuff that could be simplified, but I don't yet know how to do it.
I also have the Lower bound of Wilson score sql code to implement for the next/previous button, and it is quite a bit sql code to have to write 4 time. Maybe that I can insert the Wilson score in the photos table, which could simplify a lot the sql code.
It would be helpful if you could post the structure of your table - i.e. what columns/types you have and what each row represents. I'll assume that you have a table where each row represents a photo, and that each photo has an ID, filename, and various other columns that help you filter/sort (such as date, favorite, etc.).
If your filtering and sorting preferences are defined by the user, you can then use those in a single SQL query, whereby you get the full set of ordered results. For instance:
$sort = date;
$filter = favorite;
$sql = "SELECT ID, filename, [other vars here]
FROM photos
WHERE " . $filter . " = TRUE
ORDER BY ". $sort . " DESC";
$result = $db->sql_query($sql);
Now, you can use a function such as mysql_fetch_array to step through each row in your result set and populate some kind of data structure with the current, previous, and next photos.

Returning the number of records and ignoring duplicates in MySQL / PHP

I have a mySQL table with records of users who have visited my site. What I want to do is find out how many records there are in my table, but only counting duplicate values once in order to find out how many unique visitors there are.
I'm using the following code to find how many hits I'm getting each month.
$pageViews = mysql_query("SELECT * FROM JB_Statistics WHERE month='$month' ");
$numRowsPV = mysql_num_rows($pageViews) ;
while ($row = mysql_fetch_assoc($pageViews)) {
$month = $row['month'];
}
echo "<p>Month: $month, Total Hits: $numRowsPV </p>";
The table JB_Statistics also has an ip address and browser field with unique information for each hit, so is there a way of using this to modify the code above and find the unique visitors per month?
Apologies if this is straight forward but every search I carry out returns topics about only finding duplicate records.
SELECT COUNT(*) AS DistinctClicks
, COUNT(DISTINCT IpAddress) AS DistinctIpAddresses
, COUNT(DISTINCT Browser) AS DistinctBrowsers
, COUNT(DISTINCT IpAddress, Browser) AS DistinctUsers --- hopefully
FROM JB_Statistics
WHERE month='$month'
Not accurately based on your description.
The above answers are correct in terms of SQL, you could use a GROUP BY or DISTINCT clause but IP address does not give you unique visitors. There can be any number of users behind a single IP.
You may have to rethink what you're using to identify what's unique about each record.
You can use:
$pageViews = mysql_query( "SELECT COUNT(DISTINCT uniquefield) FROM JB_Statistics WHERE month='$month'" );
$row = mysql_fetch_array( $pageViews );
echo "<p>Month: $month, Total Hits: ", $row[0], "</p>";
Modify your query in the following way:
SELECT COUNT(DISTINCT ipfield) FROM JB_Statistics WHERE month='$month'"
That should produce what you want.
use GROUP BY: SELECT COUNT(*) FROM JB_Statistics WHERE month='$month' GROUP BY ip_address

Categories