Count records from multiple tables in real-time - php

I want to count a record by current date from different tables and return as one row with different column in the new table. The code will update a record every three hours and insert new record if current date changes. I've current date and time data (2013-05-20 14:12:12) in "created_at" column. Here my current code:
require_once('./db_connect.php');
$dbcon = new db;
//test to see if a specific field value is already in the DB
public function in_table($table,$where) {
$query = 'SELECT * FROM ' . $table . ' WHERE ' . $where;
$result = mysqli_query($this->dbh,$query);
$this->error_test('in_table',$query);
return mysqli_num_rows($result) > 0;
}
//running in background
while (true) {
$select= "SELECT (SELECT CURDATE()) AS time," .
"(SELECT COUNT(tweet_id) FROM tweets WHERE created_at= 'CURDATE() %') AS total_count," .
"(SELECT COUNT(fid) FROM fun WHERE ftime= 'CURDATE() %') AS f_count," .
"(SELECT COUNT(sid) FROM sad WHERE stime= 'CURDATE() %') AS s_count";
$results = mysqli_query( $dbcon, $select );
while($row = mysqli_fetch_assoc($result)) {
$time = $row['time'];
$total = $row['total_count'];
$fcount = $row['f_count'];
$scount = $row['s_count'];
$field_values = 'time = "' . $time . '", ' . 'total_count = ' . $total . ', ' . 'fun_count = ' . $fcount . ', ' . 'sad_count = ' . $scount;
if ($dbcon->in_table('count','time= "' . $time . '"')) {
$update = "UPDATE count SET $field_values WHEN time= '$time'";
mysqli_query( $dbcon, $update );
}
else {
$insert = "INSERT INTO count SET $field_values";
mysqli_query( $dbcon, $insert );
}
}
//update record every 3 hour
sleep(10800);
}
With this code I can't get a count record. The result return | 2013-05-18 | 0 | 0 | 0 |. How can I correct this?

I not familiar with PHP, but you can retrieve the count of all records dated any time today using:
SELECT COUNT(tweet_id)
FROM tweets
WHERE created_at >= curDate()
AND created_at < date_add(curDate(), interval 1 day)
It is equivalent to saying
..
WHERE created_at >= (today at midnight *incusive*)
AND created_at < (tomorrow at midnight *exclusive*)
Update:
The advantage of this method is it is index friendly. While using WHERE DATE(Column) = currDate() works, it can prevent the database from using indexes on that column, making the query slower.

Replace the parts where you have this:
WHERE created_at= 'CURDATE() %'
with this:
WHERE DATE(created_at) = CURDATE()
Your existing WHERE clause is comparing created_at to the string constant CURDATE() %, and they'll never match.

You are comparing against created_at= 'CURDATE() %', which is looking for that exact string, not for the result of a function. If the field created_at is a date, it will never match.
And, you are doing that for all counts.

Related

Why doesnt this update update the score?

I am trying to create an update that whenever the user gets an offer lower than the last day/week average price they get points for it 50 for last day and 20 for last week
I am desperate I have been trying for the longest time to chage thing on the proyect and now when I try to update that for every time the condition is met to update the db, it does its work and see when the price is cheaper and where it isnt but never increases the score which bugs me a lot¿can someone help?
function check_if_offer_cheaper_with_twenty_than_previous_day($prodname, $price)
// Check if the price found by the user is 20% lower than the most recent available average price of the previous day
{
global $db;
$sql = 'SELECT AVG(prices.price) >"' . $price / 0.8 . '" AS cheaper_than_previous_day'
. " FROM prices"
. ' WHERE prices.prodname = "' . $prodname . '"' .
' AND prices.date = CURDATE() - INTERVAL 1 DAY';
$result = mysqli_query($db, $sql);
$row = mysqli_fetch_assoc($result);
if (isset($row['cheaper_than_previous_day'])) {
$query = "UPDATE users SET total_score = total_score +50,
score_this_month = score_this_month + 50 WHERE id = '" . $_SESSION['user']['id'] . "'";
mysqli_query($db, $query);
return $row['cheaper_than_previous_day'];
} else {
return true;
}
}
function check_if_offer_cheaper_with_twenty_than_previous_week($prodname, $price)
// Check if the price found by the user is 20% lower than the most recent average price available in the previous week
{
global $db;
$sql = 'SELECT AVG(prices.price) > "' . $price / 0.8 . '" AS cheaper_than_previous_week'
. " FROM prices"
. ' WHERE prices.prodname = "' . $prodname .
'" AND prices.date BETWEEN CURDATE() - INTERVAL 8 DAY AND CURDATE() - INTERVAL 1 DAY';
$result = mysqli_query($db, $sql);
$row = mysqli_fetch_assoc($result);
if (isset($row['cheaper_than_previous_week'])) {
$query = "UPDATE users SET total_score = total_score +20, score_this_month = score_this_month +50
WHERE id = '" . $_SESSION['user']['id'] . "'";
mysqli_query($db, $query);
return $row['cheaper_than_previous_week'];
} else {
return true;
}
}
MySQL syntax uses commas to separate the assignment pairs, like this
$query = "UPDATE users SET total_score = total_score +20,
score_this_month = score_this_month +50
WHERE id = '" . $_SESSION['user']['id'] . "'";
dev.mysql 8.0 update syntax
That is assuming that $_SESSION['user']['id'] does not evaluate to null.

php and mysql query to get date of the last 12 months

I have a php function to get dates for a morris pie chart and it was working fine.
But now that I have more data (date for the last year and the first 3 months of this year). It's now displaying duplicate months. In this case february of last year and this years data is now showing on the same pie chart.
I'd like to write a some mysql code in php that will only display the last 12 months. I have the following code:
function writesql($rec) {
$year = date('Y') -1;
$month = date('m');
$lastyear = $year - $month; // I know this is a problem.It's subtracting the two variables
$sql = "";
$sql = $sql . " SELECT";
$sql = $sql . " YEAR(`value`)as 'Year',";
$sql = $sql . " MONTH(`value`)as 'Month',";
$sql = $sql . " `value` , ";
$sql = $sql . " COUNT(`value`) as 'Calls' ,";
$sql = $sql . " ROUND(SUM( `value` ),2) as 'Value'";
$sql = $sql . " FROM `table`";
$sql = $sql . " GROUP BY";
$sql = $sql . " YEAR(`value`),";
$sql = $sql . " MONTH(`value`)" ;
$sql = $sql . " ORDER BY";
$sql = $sql . " YEAR(`value`),";
$sql = $sql . " MONTH(`value`)";
$sql = $sql." WHERE (`value`)='".$lastyear."'";// I also know this is wrong too but im lost as to how to fix it.
return $sql;
}
Then the rest follows, I only want to get the data for the last 12 months how should I be executing this.
You could do WHERE value >= DATE_SUB(CURDATE(),INTERVAL 1 YEAR);
This would show 12 months up to the current date.
You are close. Make these changes
$year = date('Y') -1; // This will give last year
$sql." WHERE YEAR(`value`)='".$year."'"
Updated Query
$sql = "
SELECT YEAR(`value`) as 'Year', MONTH(`value`) as 'Month', `value`,
COUNT(`value`) as 'Calls', ROUND(SUM( `value` ),2) as 'Value'
FROM `table`
WHERE YEAR(`value`) = '$year'
GROUP BY YEAR(`value`), MONTH(`value`)
ORDER BY YEAR(`value`), MONTH(`value`)";
First off, I find this easier to read:
$sql = "
SELECT YEAR(value) Year
, MONTH(value) Month
, value
, COUNT(value) Calls
, ROUND(SUM(value),2) Value
FROM `table`
GROUP
BY YEAR(value)
, MONTH(value)
ORDER
BY YEAR(value)
, MONTH(value)
WHERE (value) = '".$lastyear."'
";
But this query is syntactically incorrect. So here's a syntactically correct version:
$sql = "
SELECT YEAR(`value`) Year
, MONTH(`value`) Month
, COUNT(value) Calls
, ROUND(SUM(value),2) Total_Value
FROM `table`
WHERE value = '".$lastyear."'
GROUP
BY YEAR(value)
, MONTH(value)
ORDER
BY YEAR(value)
, MONTH(value);
";
Now see about prepared and bound queries

Can't get score to update with this mysql statement

I'm guessing that I'm just a little rusty or something because it seems like this should be working. Am I missing something here...
Here is the code I am trying to use...
<?php
echo dbConn();
$existing_time = mysql_result(mysql_query("SELECT p_time FROM scores WHERE p_uid=$uid"), 0);
$existing_category = mysql_result(mysql_query("SELECT p_cat FROM scores WHERE p_uid=$uid AND p_cat=$pieces"), 0);
if ($existing_category == "") {
mysql_query(
"INSERT INTO scores VALUES (
'',
'$uid',
'$pusername',
'$time',
'$pieces'
)");
} elseif ($existing_time <= $time) {
echo "No Change! Old Score Was Better (Lower)";
} elseif ($existing_time > $time) {
mysql_query("UPDATE scores SET p_time = " . $time . " WHERE p_uid = " . $uid . " AND p_cat = " . $pieces . "");
};
?>
Now... Here is what I am trying to do...
I am collecting info from the database where the users username AND category match. If the category for that user does not exist, it inserts the latest score. (This much works.)
Then, if the category does exist but the old score is better, it just does nothing. (This part works too)...
However, what I can't seem to do is get it to update the last score, if the current score is better (lower score, since this is a time based game.) It doesn't update the score.
I am trying it this way: By updating a row in "scores" where the USERNAME and the CATEGORY match at the same time.
Please note... where it says "pieces". this is a category. Where it says "time", this is a score. The score is returned as 00:00:00 for hours minutes and seconds.
EXAMPLE: (in parentheses is the database row name)
id (ID) = just KEY id in sequencial order
user id (p_uid) = 123456789
username (p_username) = somename
score (p_time) = 00:01:03
category (p_cat) = 10
Change you update statement to:
mysql_query("UPDATE scores SET p_time = '" . $time . "' WHERE p_uid = " . $uid . " AND p_cat = " . $pieces . "");
You have missed quotes in the update statement around $time.

Select records from MYSQL database grouped by day

I have a database of records that have a timestamp asscoiated with them. I would like to pull records from the database grouped by day, so if there are other records with the same date (24 hour span) I would like them to be grouped together. Can this be done with MYSQL or will I have to pull the records and organise them into arrays using PHP?
Here is a screenshot of my table:
Here is my model function so far:
public function getUsersMoves($options) {
$query = "SELECT * FROM myzone_user_hr_records";
if(isset($options['GUID'])) {
$query .= " WHERE GUID = '" . $options['GUID'] . "'";
}
if((isset($options['minHR'])) && isset($options['maxHR'])) {
$query .= " AND (hr BETWEEN '" . (int)$options['minHR'] . "' AND '" . (int)$options['maxHR'] . "')";
} else if (isset($options['zone'])) {
$query .= " AND zone = '" . (int)$options['zone'] . "'";
}
if(isset($options['activity'])) {
$query .= " AND title = '" . $options['activity'] . "'";
}
$query .= " ORDER BY time DESC";
$query = $this->db->query($query);
return $query->result_array();
}
And my controller code:
$moves = $this->myzone_model->getUsersMoves($options);
I want the data sorted so that these records are grouped together if they have the same date in the timestamp, for example (2012-11-20).
Thanks
try this :
SELECT *, DATE(time) AS date FROM [whatever you want] GROUP BY date
select * from TABLE where `time` like '2012-11-20%'
The option I have suggested works because the LIKE condition in the WHERE selects all dates from the time field that start with 2012-11-20. That means that it doesn't matter what time it is during the day, it will return all results for that day.
To make this work, you must remember to use LIKE and then add the wildcard at the end - %. You can also add the wildcard at the beginning if you wanted. An example to return all days (11th December) for multiple years would be:
SELECT * FROM TABLE WHERE `time` like '%-12-11%'

How to control last visitor ip through sql and php?

I am trying to make a unique visitors counter for my pages using mysql and php. Im my DB table i have a "views" column and a "last_ip" column.
If the ip of the current user is equal to the last ip stored on DB the counter dies, if the current user ip is different from the last ip stored on DB the current user ip is stored as last ip on DB and the counter sums +1 to the views on DB.
The main idea is:
1 - check the ip of the current user and save it to variable $viewer_ip
2 - check the last ip stored on DB and save it to variable $last_viewer_ip
3 - compare those 2 variables, if $viewer_ip =! $last_viewer_ip the function should store $last_viewer_ip in "last_ip" field and sums +1 in "views" field. Else it should do nothing.
<?php
$viewer_ip = $user_ip = $h->cage->server->testIp('REMOTE_ADDR');
$sql = "SELECT post_last_viewer_ip FROM " . TABLE_POSTS . " WHERE post_id = %d";
$last_viewer_ip = $h->db->get_var($h->db->prepare($sql, $h->post->id));
if ($viewer_ip AND $viewer_ip != $last_viewer_ip) {
$sql = "UPDATE " . TABLE_POSTS . " SET post_last_viewer_ip = '" . $viewer_ip . "' WHERE post_id = %d";
$h->db->query($h->db->prepare($sql, $h->post->id));
}
if ($viewer_ip != $last_viewer_ip) {
$sql = "UPDATE " . TABLE_POSTS . " SET post_views = post_views + 1 WHERE post_id = %d";
$h->db->query($h->db->prepare($sql, $h->post->id));
}
?>
that code works in parts, cause it sums like 3 views, on each visit, as u can see, that code is a trash, cause i did it myself and i am no expert.
Anyone can try a fix on this? ty.
You need to store the session id of your visitors to the database to be able to do that kind of thing correctly. A unique visitor is considered one that is there for one specific session. If the user closes the browser and comes back, then it is another visitor.
If you want truly unique visitors, you need to store cookies too and use them to identify your visitors, but then again, cookie blocked? Cookie flushed? You're screwed...
Last method is to force a login, with a login you usually have a user_id, that user_id becomes your unicity.
I'll let you decide how you want to handle your unicity...
For the storage part, you need at least 1 table where you store the requests and identity of your requesters. Store in that table the following information:
Page/SpecificRequest
UserIP/SessionID/CookieID/UserId
RequestDate
RequestTime
Then on each page request, store a request in that table such as:
INSERT INTO myrequests VALUES(
$_REQUEST['URI'],
session_id(),
date('Y-m-d'),
date('G:i:s')
)
And then, to retrieve the unique visitor count, you just group on the data:
SELECT RequestDate, COUNT(*) AS uniquevisitors
FROM myrequests
GROUP BY RequestDate, session_id()
Good luck
Try it this way..
You need one separate table (TABLE_WITH_LOGS) for IP logs, which has 3 columns post_viewer_ip varchar(15), timestamp timestamp, post_id bigint (or whatever type you have for you post ids).
The code will look something like that one..
$timeout = 30*60; // count as a new visit after 30 minutes
$viewer_ip = $user_ip = $h->cage->server->testIp('REMOTE_ADDR');
// check if there is a record within the timeout period
$sql = "SELECT count(*) FROM " . TABLE_WITH_LOGS . " WHERE post_id = %d
AND ip = '%s' AND `timestamp` > NOW() - $timeout";
$rows = $h->db->get_var($h->db->prepare($sql, $h->post->id, $viewer_ip));
if ($rows == 0) { // no recent records in DB, insert new one
$sql = "INSERT INTO " . TABLE_WITH_LOGS . " SET post_viewer_ip = '" .
$viewer_ip . "', `timestamp` = NOW() WHERE post_id = %d";
$h->db->query($h->db->prepare($sql, $h->post->id));
// update counter
$sql = "UPDATE " . TABLE_POSTS . " SET post_views = post_views + 1
WHERE post_id = %d";
$h->db->query($h->db->prepare($sql, $h->post->id));
}
else { // there is at least one record, update it with current timestamp
$sql = "UPDATE " . TABLE_WITH_LOGS . " SET `timestamp` = NOW()
WHERE post_id = %d and post_viewer_ip = '$viewer_ip' LIMIT 1";
$h->db->query($h->db->prepare($sql, $h->post->id));
}
// cleanup table from time to time
if (rand(1,5)<2) {
$sql = "DELETE " . TABLE_WITH_LOGS . " WHERE `timestamp` < NOW() - $timeout";
$h->db->query($sql);
}
ps: you may skip part with timestamp update and always insert a new record. It will make less (only by one :)) SQL requests.
$timeout = 30*60; // count as a new visit after 30 minutes
$viewer_ip = $user_ip = $h->cage->server->testIp('REMOTE_ADDR');
// check if there is a record within the timeout period
$sql = "SELECT count(*) FROM " . TABLE_WITH_LOGS . " WHERE post_id = %d
AND ip = '%s' AND `timestamp` > NOW() - $timeout";
$rows = $h->db->get_var($h->db->prepare($sql, $h->post->id, $viewer_ip));
if ($rows == 0) { // no recent records in DB, update counter
$sql = "UPDATE " . TABLE_POSTS . " SET post_views = post_views + 1
WHERE post_id = %d";
$h->db->query($h->db->prepare($sql, $h->post->id));
}
// record last visit
$sql = "INSERT INTO " . TABLE_WITH_LOGS . " SET post_viewer_ip = '" .
$viewer_ip . "', `timestamp` = NOW() WHERE post_id = %d";
$h->db->query($h->db->prepare($sql, $h->post->id));
// cleanup table from time to time
if (rand(1,5)<2) {
$sql = "DELETE " . TABLE_WITH_LOGS . " WHERE `timestamp` < NOW() - $timeout";
$h->db->query($sql);
}

Categories