Grouping and counting results based on column PHP Mysql - php

I have a table recording hits to pages like this :
id | ip_address | page_id
---------------------------------------
1 | 192.123.456.78 | 2787321
2 | 192.000.000.00 | 2787321
3 | 192.123.456.78 | 342415
4 | 192.123.456.78 | 2787321
5 | 192.432.999.80 | 2787321
I'm getting the results like this :
$getHits = $wpdb->get_results( "SELECT * FROM $table WHERE page_id = $pageID" );
I want to display the results grouped by ip_address based on how many times each IP accessed the same page_id.
Example of desired output (where $pageID = 2787321) :
192.123.456.78 - 2 Views
192.000.000.00 - 1 View
192.432.999.80 - 1 View
I've been trying a few things (grouping mainly and running through while and foreach loops) but it quickly got really complicated and I can't get it to work.
Could somebody point me in the right direction please?

You should not use var for dinamic query you are at risk of sqlinjection
anyway
$wpdb->get_results( "SELECT ip_address, count(*) hits
FROM $table WHERE page_id = $pageID
GROUP BY ip_address
ORDER BY hits DESC" );
http://www.mysqltutorial.org/mysql-group-by.aspx

Related

PHP collect and combine different data from two tables

I have these two tables which I'm trying to make an output of.
The first one **USERS** stores all information about a user, including an unique ID (androidID).
The second one gets input based on number of laps a user has taken, and will make one row pr lap.
What I'm trying to do is to output the last entry of a given androidID in **ROUNDS**, whith the corresponding name etc. from **USERS**
_____________________ _________________________
| **USERS** | | **ROUNDS** |
--------------------- -------------------------
| NAME | | ID(unique) |
| LASTNAME | | TIME |
| androidID(unique) | <----> | androidID(NOT unique) |
| ... | | ROUNDS |
This is how I'm quering the server
$result_users = $con->query(
"SELECT * FROM users"
);
$result_rounds = $con->query(
"SELECT * FROM Rounds ORDER BY laps desc"
);
I tried to numerous combination of the following. With no luck. My PHP skills is not the best, I'm afraid.
foreach ($result_users as $row_users) {
foreach ($result_rounds as $row_rounds) {
if($row_users['androidID'] == $row_rounds['androidID'] {
// Do some wizzardy
}
}
}
I have really hit a wall trying to connect the tables.
This would be the sql statement you want in your query.
SELECT * FROM `**USERS**` LEFT JOIN `**ROUNDS**`ON `**USERS**`.`androidID` = `**rounds**`.`androidID` ORDER BY `laps` desc 0,1;

Display TIMEDIFF result from mySQL query to webpage

Me again, guys. The titles is pretty self-explanatory, but for the details:
I want to display the timediff(in hours) results on a webpage but I can't wrap my head around how to do it.
I'm using PHP and Codeigniter for this website.
So far, I have a mySQL database with a table named 'server_log' which looks like:
+--------+-----------+--------+---------+------------+-------------+
| log_id | host_name | status | host_id | profile_id | event_date |
+--------+-----------+-+----------------+------------+-------------+
| 1 | http://...| Online | 1 | 1 | *timestamp* |
+--------+-----------+--------+---------+--------------------------+
*It shows also other entries with status "Offline" and "Maintenance".
I have this query to get the entries per user (based on profile_id) w/c are also sorted by status ('Online','Offline', or 'Maintenance'):
SELECT * FROM server_log
WHERE (profile_id=$id AND status='Online')
AND event_date BETWEEN $from_date AND $to_date
ORDER BY event_date,host_id;
*the from_date and to_date are results from the webpage which lets the user choose a 'From' and 'To' date to filter the results like a report page.
The problem I have is that after the above query I do not know what I else I need in order to calculate the TIMEDIFF results for each server(host_id) then display them on the webpage. (I'd like to get the TIMEDIFF between the results after getting the query results for each status)
How do I get the TIMEDIFF result (integer)?
Simply put, I want the flow to be like this:
[1] After 1st query: (SELECT ALL 'Online' for $id)
log_id | host_name | status | host_id | profile_id | event_date
1 ping.test1 Online 1 2 **
2 ping.test1 Online 1 2 **
3 ping.test2 Offline 2 2 **
4 ping.test2 Offline 2 2 **
[2] After 2nd query: (loop for each host_id)
log_id | host_name | status | host_id | profile_id | event_date
1 ping.test1 Online 1 2 **
2 ping.test1 Online 1 2 **
-> then calculate diff_date of event_dates
---> then return value to be assigned to $data['reports_ping']
-----> back to [1] but selecting all 'Offline', then 'Maintenance'
-------> if all values are assigned, display $data['reports_ping'] as row (foreach)
I would like the results to show something like:
+------------+------------+------------+-------------+-------------+
| profile_id | host_name | online_hrs | offline_hrs | maintenance |
+------------+------------+------------+-------------+-------------+
| 1 | http://... | 2 | 1 | 0 |
+------------+------------+------------+-------------+-------------+
I'm relatively a beginner and not really that good with CodeIgniter, so any help with this would be REALLY appreciated. Thanks in advance!
TIMEDIFF meaning different time between event_date and now? Try this :
SELECT *, (event_date - NOW()) as TIMEDIFF FROM server_log
WHERE (profile_id=$id AND status='Online')
AND event_date BETWEEN $from_date AND $to_date
ORDER BY 'event_date','host_id';
-- EDIT --
Is this the logic you want?
$temp = null;
foreach($rows){
$event_date = "select event_date from server_log order by log_id LIMIT 1"; // specify this query using your CI format
$timediff = $event_date - $temp;
$temp = $event_date;
}

User Wall PHP and MYSQL

I'm working on a big project a social networking site but now I'm stuck and i need your advice.
My problem is that I wan't to display everything like posts, videos and statuses into his profile.php under user timeline.
I got more than 40 Tables but let me specify what I wan't, I wan't to get data from these tables and how to display them on the profile.php timeline section ?
Status Table
------------------------------------------
ID | sMessage | sDate | uId
------------------------------------------
1 | Testing status | 2013/07/03 | 1
Videos Table
-----------------------------------------------------
ID | vName | vCode | vDate | uId
-----------------------------------------------------
1 | PHP and MYSQL | 2MvYwz | 2013/07/03 | 1
Users Table
-----------------------------------
ID | uName | JoinDate
-----------------------------------
1 | Tem Henov | 2013/07/03
And here is what i tried:
class userTimeline {
public function loadTimeline(){
dbConn();
$query = "SELECT
sMessage, sDate, vName, vDate, vCode
FROM status
INNER JOIN users
ON (status.uId = users.uId)
INNER JOIN videos
On (videos.uId = users.uId)
WHERE users.uId = '1'";
return $result = mysql_query($query);
}
}
and its loads the data fine but how to display that data in blocks like if its a status display in a separate block and if its a video display it in another block and how to order by date ?! any help is appreciated.
First : To Show data into various <div> first fetch them and show like,
1) Fetch all the record and store into a php array
$rows = array();
while($row = mysql_fetch_array(YOUR_QUERY))
{
$rows[] = $row;
}
2) Now Using foreach() loop use data fetched from query where ever you want
if(is_array($rows)) {
foreach($rows as $row) {
//do with $row or create some if,switch condition here !
}
}
For specific limits and tweaks study the result set we get from mysql_fetch_array() !
Second : To short data by date you can use multiple sorting (click here for
tutorial) but i think you should use MYSQL UNION to merge two
or more MySQL query results to get individual sorting result.

Exploding in php

In my table 'users' there are 'friends' ,
Like this :
+----+------+---------+
| id | name | friends |
+----+------+---------+
| 1 | a | 0,1,2 |
| 2 | b | 0,1,3 |
| 3 | c | 0,1 |
+----+------+---------+
How do I use the explode function to get the friends id one by one (not 0,1,2) that are separated by a comma (,) ;
How do I select the id? (Example) :
$sql = Select id from users where id = (exploded)
if (mysql_num_rows($sql) > 0 ) {
$TPL->addbutton('Unfriend');
}else{
$TPL->addbutton('Add as Friend')
}
The solution here is actually a slight change in your database structure. I recommend you create a "many-to-many" relational table containing all of the users friends referenced by user.
+---------+-----------+
| user_id | firend_id |
+---------+-----------+
| 1 | 2 |
| 1 | 3 |
| 1 | 4 |
| 2 | 1 |
| 2 | 5 |
+---------+-----------+
If you are storing lists of values within one field then that is the first sign that your database design is not quite optimal. If you need to search for a numerical value, it'll always be better to place an index on that field to increase efficiency and make the database work for you and not the other way around :)
Then to find out if a user is a friend of someone, you'll query this table -
SELECT * FROM users_friends WHERE
`user_id` = CURRENT_USER AND `friend_id` = OTHER_USER
To get all the friends of a certain user you would do this -
SELECT * FROM users_friends WHERE `user_id` = CURRENT_USER
Just a simple example that will make you clear how to proceed:
// Obtain an array of single values from data like "1,2,3"...
$friends = explode(',', $row['friends']);
Then, back in your query:
// Obtain back data like "1,2,3" from an array of single values...
$frieldslist = implode(',', $friends);
$sql = "SELECT * FROM users WHERE id IN ('" . $frieldslist . "')";
to get an array of if ids from your string explode would be used like this
$my_array = explode("," , $friends);
but you'd probably be better using the mysql IN clause
$sql = "Select id from users where id in (".$row['friends'].")";
Just a quick idea. Change your database's table. It is certain that after a while many problems will arise.
You could have something like this.
id hasfriend
1 2
1 3
2 1 no need to be here (You have this already)
2 4
.....
You can do this by using indexes for uniqueness or programming. You may think of something better. Change your approach to the problem to something like this.

Fast way to find the page before and after the one I want

I'm a beginner in mysql and I wanted to know if there is a faster way to do the following:
I have a table like this:
------------------------------
| Pages | Creation |
------------------------------
| bar | 2012-10-10 10:11:10|
| blah | 0000-00-00 00:00:00|
| foo | 2012-10-10 10:10:10|
------------------------------
There is no primary key.
I want to know the page before and the page after a specific page (Ordered by date of creation).
Currently I do:
Sql: SELECT * FROM table ORDER BY creation
Php:
foreach($r as $c=>$t)
{
if($t['pages']==$thepageiwant)
{
$before=$c-1;
$after=$c+1;
break;
}
}
Previous page:
SELECT table.Pages
FROM table, (SELECT Creation FROM table WHERE Pages = "'.$page.'") AS t2
WHERE table.Creation < t2.Creation
ORDER BY table.Creation DESC
LIMIT 1
Next page:
SELECT table.Pages
FROM table, (SELECT Creation FROM table WHERE Pages = "'.$page.'") AS t2
WHERE table.Creation > t2.Creation
ORDER BY table.Creation ASC
LIMIT 1

Categories