SQL groupping by date and host address - php

I'm trying to count the unique visitors each day on my website.
This is the script i made:
<?php
require_once 'database.php';
$dateQuery = $db->prepare("SELECT count(*) AS hits FROM tracked GROUP BY DATE(date), hostadrr");
$dateQuery->execute();
$rows = $dateQuery->fetchAll(PDO::FETCH_ASSOC);
$array = array();
foreach ( $rows as $row ) {
$array[] = [(int)$row['hits']];
}
$json = json_encode($array);
echo $json;
?>
This array I get from the json_encode is then this:
[[3],[1],[1],[2],[10],[3],[1],[2]]
It is correct that there are 8 arrays inside an array, this represents each day. But the number inside each array are just the total number on clicks on my website, not grouped by the host address of the user. What am i doing wrong here? The array should be: [[1],[1],[1],[1],[1],[1],[1],[1]] (because i'm testing it on my own computer ;) )

First of all, always try to strip down your code to the minimal problem. For example, don't mix JSON encoding, PHP and MySQL and be astonished, that the result isn't what you look like.
Start with the SQL query:
SELECT count(*) AS hits FROM tracked GROUP BY DATE(date), hostadrr
Did you try to run that on console or in phpMyAdmin? Is the correct result showing up?
I would guess not. Why? Because this query only returns a number of hits without any relation to a date or a host address. So, even though you say that the data is correct for the total hits in a day, you can't even be sure if it is the right order or if it doesn't leave out days without any hits.
Since you do not provide your SQL schema, I can only assume one. But your query should at least look something like this:
SELECT
date AS date,
hostadrr AS host,
count(*) AS hits
FROM
tracked
GROUP BY
DATE(date),
hostadrr
ORDER BY
date ASC
Now, you'll get one line for each date/host combination along with the respective number of hits and you can assign that to an array, i.e.
$array[$row['date']][$row['host]] = (int) $row['hits'];

Related

Random jump within while() loop in PHP for MySQL query

I am doing an example project for University and got a problem that I can't solve.
In general, the project is to create an automated pizza order system in PHP and MySQL on Apache. The system works through the following steps:
- Customer places order -> Baker receives order, proceeds -> Driver receives order at certain state, proceeds
- Customer can view order at all time through session
Now I hung up at the last step: The driver can see a page that has a table with the information that the baker worked with and passed on (all changes are on database side). The driver can only see a whole package (whenever all pizzas are marked as a certain status, also saved in DB).
For this, I have the following SQL statement
SELECT PizzaID, BestellungID, Adresse, PizzaName, Preis, Status FROM angebot, bestelltepizza, bestellung where bestellung.bestellungid = bestelltepizza.fbestellungid and angebot.PizzaName = bestelltepizza.fPizzaName and (select min(status) from bestelltepizza where bestellung.bestellungid = fbestellungid) >2 ORDER BY Status, BestellungID
Now, when I use var_dump() to get the mysqli_num_rows() output, I get no errors and the following output int 26. Compared to the database rows, it's the correct number. I fetch the sql:
while($row = mysqli_fetch_array($this->result)) {
var_dump(mysqli_num_rows($this->result));
var_dump($row);
...
}
Within the while() loop contains another query
$this->query = "SELECT fPizzaName FROM bestelltepizza WHERE fBestellungID = '$BestellID'";
var_dump($this->query);
$tmpResult = $this->_database->query($this->query);
$count = mysqli_num_rows($tmpResult);
Now here is the problem, the while() loop leaves out a random $BestellID which can contain x rows of data. But when I count the output of var_dump() everything is correct. However, var_dump($this->query); is not showing the query statement for the specific jump, too.
Any ideas what this could be? Full link to pastebin below.
To not extend this question to the fullest, I uploaded the whole code to pastebin here: http://pastebin.com/u888CPLw
Offtopic: Appreciate any help, thanks. If I failed clearing out my exact problem or if any questions pop up to my question, please comment and I will clarify. Thanks.
while($row = mysqli_fetch_array($this->result)) {
$count = mysqli_num_rows($tmpResult);
for($i = 0; $i < $count; $i++) {
$tmpVar = mysqli_fetch_array($this->result);
Ive snipped the code to show the problem
$count is based on $tmpResult you are then doing a fetch array on $this->result you should be doing it on $tmpResult
As Marc B says, Its a simple query to either inner join / left join on to the query. It would be better to use the join.

Multiple MYSQL Statements executed as a single statement

I've got a bit of a problem with my code. I'm sure that it is something simple, but I just can't figure it out! I have been on tons of forums and have read several books... but every answer that I have worked to has failed. I almost guarantee that it's the way that I am using my syntax (and yes I know... procedural PHP is not really used anymore) but I am really a bit of a newbie to this and I am just trying to pick up the basics before moving onto OOP and PDO connections.
Could you please help me? At the moment I can get the user to select their date from the date picker and the results specifically from that date only will return... only problem is that the event is displaying the event_id as opposed to the name of the event that it relates to (1 = 5km run) for example.
Somehow I need to access the events table and pull the row that relates to that specific event_id.
I have normalized my database, and according to my tutor it looks ok. To give you an idea what it looks like - logins table (all user logins details), results table (a history of submitted events) events table (the events themselves).
On the results table the foreign keys are logins_id and the event_id. The primary key is the results_id in the results table and the only data stored here is the time and data (individual columns).
<?php // -----Stage 1. On submission of the form run the following -----//
if (isset($_POST['submit_d'])) {
$mydate = $_POST ['MyDate'];
$my = preg_replace('/[^a-zA-Z0-9]+/', ' ', $mydate);
if ($mydate) {
$result = mysql_query("SELECT * FROM logins WHERE username = '$username' LIMIT 1");
//This function will take the above query and create an array...
while($row = mysql_fetch_array($result))
{
//With the array created above, I can create variables (left) with the outputted array (right)
$logins_id3 = $row['logins_id'];
}
$sql = "SELECT * FROM results where $logins_id3 AND date = $mydate ";
/* ----- Here is the code that I want to use in conjunction with the above statement --->
$query = "SELECT logins.username,events.event,results.time,results.date,logins.age,logins.gender
FROM logins INNER JOIN results ON logins.logins_id=results.logins_id INNER JOIN events ON results.event_id=events.event_id
ORDER BY time ASC LIMIT 10";
*/
$resultz = mysql_query($sql);
if( mysql_num_rows($resultz) ) {
while ($row = mysql_fetch_array($resultz)) {
echo "<table><tr><th>Username</th><th>Event</th><th>Time (HH:MM:SS)</th><th>Date (YY/MM/DD)</th><th>Age</th><th>Gender</th>
</tr><tr><td>".$username."</td>"
."<td>".$row['event_id']."</td>"."<td>".$row['time']."</td>"." <td>".$row['date']."</td>"."<td>".$row['age']."</td>".
"<td>" $row['gender']."</td></tr></table>";
}
}
}
}
?>
The other thing I would like to do.. although this is not crucial, is to strip special characters from the input. Basically I'm using a jquery calendar picker and I want the user to be able to select their date in the 2014-05-26 format and the php to remove the - before it is submitted to the database, that way it doesn't effect the users experience but it will work with my current code.
Anyways sorry to waffle on, any help on either of these matters would be much appreciated!
Yours Sincerely:
Peter Scales.
You can use a join to get the data that relates to the event ID:
SELECT * FROM results r LEFT JOIN events e ON r.event_id = e.event_id WHERE ...
You can then select where "e.event_id = $event_id"; and the rest of your query logic.
You can also filter out any unwanted characters by using preg_replace: http://ar2.php.net/preg_replace

How to get the number of results MySql would have returned without limit?

I have a table with a lot of data, so I retrieve it and display it one page at a time (my request is lengthy so there is no way I run it on the entire table).
But I would like to paginate the results, so I need to know what is the total number of elements in my table.
If I perform a COUNT(*) in the same request, I get the number of selected elements (in my case, 10).
If I perform a COUNT(*) on my table in a second request, the result might be wrong because of the where, join and having clauses in my main query.
What is the cleanest way to:
Retrieve the data
Know the maximum number of elements in my table for this specific request
One solution seems to be using the Mysql function FOUND_ROWS :
I tried this, as mysql_query performs one query at a time: (taken here)
$query = 'SELECT SQL_CALC_FOUND_ROWS * FROM Users';
$result = mysql_query($query);
// fetching the results ...
$query = 'SELECT FOUND_ROWS()';
$ result = mysql_query($query);
// debug
while ($row = mysql_fetch_row($result)) {
print_r($row);
}
And I got an array with 0 results:
Array ( [0] => 0 )
Whereas my query does returns results.
What is wrong with my approach ? Do you have a better solution ?
Set mysql.trace_mode to Off if it is On.
ini_set('mysql.trace_mode','Off'); may also work depending on your host configuration if you cannot edit my.cnf
If that doesn't make the code you posted above work, then you will need to run the query again without LIMIT and count it that way.
The code above works fine. I wasn't opening the connection correctly.
Output is :
Array ( [0] => 10976 )
I am still interested for an other way to do it, especially something that is not mysql dependent.

Php - Mysql. Get players into an array and sort by time

I'm trying to create an array, and then sort the objects by time, from a mysql_query.
This is what happens:
When a player has completed his turn, I update the database. I set the database variable "lastTurn" to the current time.
$nickname = $_POST['name'];
$lastTurn = date();
$myTurn = NO;
$query ... update query
Now I need to find out who the next player is, and send the turn to him/her.
$query = "SELECT * FROM active_users_table WHERE match_id='12345'
This gives me all the player associated with the current game.
But now I don't know how to continue.
I want to put all the players into an array, and then sort it after turnDate i guess, to see who the next player is. Like a poker game. I also need to check another variable in the database, "havePlayerLost", to see if he still is active in the game. If he have lost, then get the next player who is active, and with the highest turnDate.
Any advice is very appreciated.
Thanks
I would suggest you let MySQL/SQL do a little more work than you're doing right now. The SQL query you use to update the player, can also contain the current date / time in the right format.
player_lastTurn = NOW()
When it comes to sorting your array, I'd suggest you let MySQL handle this one aswell:
ORDER BY player_lastTurn ASC
ASCending means it will give you the oldest DateTime for that cellname within the entire database.
When you use the results of these queries and build your array using it, you're array will automatically be in the correct order.
The same applies for the "lost players", so you automatically not include them in the array when you're not loading it.
To get the player sorted try to change the query adding ' ORDER BY turnDate ASC '
$query = "SELECT * FROM active_users_table WHERE match_id='12345' ORDER BY turnDate ASC"
For the variable "havePlayerLost" I think you can change the query too like this adding ' havePlayerLost = false '
$query = "SELECT * FROM active_users_table WHERE match_id='12345' AND havePlayerLost = false ORDER BY turnDate ASC"
try this query
$query = "SELECT * FROM active_users_table WHERE match_id='12345'
and status !='havePlayerLost'
order by lastTurn Asc

debugging a mysql insert fail in php

I'm having problems debugging a failing mysql 5.1 insert under PHP 5.3.4. I can't seem to see anything in the mysql error log or php error logs.
Based on a Yahoo presentation on efficient pagination, I was adding order numbers to posters on my site (order rank, not order sales).
I wrote a quick test app and asked it to create the order numbers on one category. There are 32,233 rows in that category and each and very time I run it I get 23,304 rows updated. Each and every time. I've increased memory usage, I've put ini setting in the script, I've run it from the PHP CLI and PHP-FPM. Each time it doesn't get past 23,304 rows updated.
Here's my script, which I've added massive timeouts to.
include 'common.inc'; //database connection stuff
ini_set("memory_limit","300M");
ini_set("max_execution_time","3600");
ini_set('mysql.connect_timeout','3600');
ini_set('mysql.trace_mode','On');
ini_set('max_input_time','3600');
$sql1="SELECT apcatnum FROM poster_categories_inno LIMIT 1";
$result1 = mysql_query($sql1);
while ($cats = mysql_fetch_array ($result1)) {
$sql2="SELECT poster_data_inno.apnumber,poster_data_inno.aptitle FROM poster_prodcat_inno, poster_data_inno WHERE poster_prodcat_inno.apcatnum ='$cats[apcatnum]' AND poster_data_inno.apnumber = poster_prodcat_inno.apnumber ORDER BY aptitle ASC";
$result2 = mysql_query($sql2);
$ordernum=1;
while ($order = mysql_fetch_array ($result2)) {
$sql3="UPDATE poster_prodcat_inno SET catorder='$ordernum' WHERE apnumber='$order[apnumber]' AND apcatnum='$cats[apcatnum]'";
$result3 = mysql_query($sql3);
$ordernum++;
} // end of 2nd while
}
I'm at a head-scratching loss. Just did a test on a smaller category and only 13,199 out of 17,662 rows were updated. For the two experiments only 72-74% of the rows are getting updated.
I'd say your problem lies with your 2nd query. Have you done an EXPLAIN on it? Because of the ORDER BY clause a filesort will be required. If you don't have appropriate indices that can slow things down further. Try this syntax and sub in a valid integer for your apcatnum variable during testing.
SELECT d.apnumber, d.aptitle
FROM poster_prodcat_inno p JOIN poster_data_inno d
ON poster_data_inno.apnumber = poster_prodcat_inno.apnumber
WHERE p.apcatnum ='{$cats['apcatnum']}'
ORDER BY aptitle ASC;
Secondly, since catorder is just an integer version of the combination of apcatnum and aptitle, it's a denormalization for convenience sake. This isn't necessarily bad, but it does mean that you have to update it every time you add a new title or category. Perhaps it might be better to partition your poster_prodcat_inno table by apcatnum and just do the JOIN with poster_data_inno when you need the actually need the catorder.
Please escape your query input, even if it does come from your own database (quotes and other characters will get you every time). Your SQL statement is incorrect because you're not using the variables correctly, please use hints, such as:
while ($order = mysql_fetch_array($result2)) {
$order = array_filter($order, 'mysql_real_escape_string');
$sql3 = "UPDATE poster_prodcat_inno SET catorder='$ordernum' WHERE apnumber='{$order['apnumber']}' AND apcatnum='{$cats['apcatnum']}'";
}

Categories