Hope Someone Can help I'm trying to build a table of Daily Sales, and display a table where each sales person can see their daily results on a weekly basis. Im sure its not overly difficult but ive been scratching my head on this one, im new to php and MySQL have been finding my way though it ok but this has got me
The Result I'm Trying to achieve will look something like this.
-------------------------------------------------
|Name | sun | mon | tue | wed | thu | fri | sat |
-------------------------------------------------
|pete | 0 | 0 | 0 | 200 | 200 | 0 | 0 |
-------------------------------------------------
|mike | 0 | 0 | 0 | 0 | 100 | 0 | 100 |
-------------------------------------------------
An example of the table im using is ...
------------------------------------------------
| order_number | order_value | user_name | Date |
-------------------------------------------------
| 1 | 100 | pete | 10/7 |
-------------------------------------------------
| 2 | 200 | mike | 13/7 |
-------------------------------------------------
| 3 | 100 | pete | 10/7 |
-------------------------------------------------
| 4 | 100 | mike | 11/7 |
-------------------------------------------------
| 5 | 200 | peter | 11/7 |
-------------------------------------------------
The code im currently using at the moment is as follows Not sure if im better off manipulating this data via php code or using a better SQL query.
$sql = mysqli_query($mysqli," SELECT SUM(order_value) , DAYOFWEEK(Date) , `user_name`
FROM `my_table`
WHERE WEEK(Date) = $thisweek -1 AND YEAR(Date) = $currentYear
GROUP BY user_name , DAYOFWEEK(Date)");
echo "
<table border ='1'>
<tr><td>Name</td><td>sun</td><td>mon</td><td>tue</td><td>wed</td><td>thu</td><td>fri</td><td>sat</td></tr>";
while($result=mysqli_fetch_array($sql))
{
$i = $result['DAYOFWEEK(Date)'];
$v = $result['SUM(order_value)'];
$n = $result['user_name'];
$d = $i;
echo "<td>" . $n . "</td>";
for($d=1; $d<=7; $d++ )
{
if($v >0 && $d == $i)
{
echo "<td>" . $v . "</td>";
}
else
{
echo "<td>0</td>";
}
}
echo"</tr>";
}
echo "</table>";
From this code the result im getting itis close but I want it flattened so each user only appears once in the table,
-------------------------------------------------
|Name | sun | mon | tue | wed | thu | fri | sat |
-------------------------------------------------
|pete | 0 | 0 | 0 | 200 | 0 | 0 | 0 |
-------------------------------------------------
|pete | 0 | 0 | 0 | 0 | 200 | 0 | 0 |
-------------------------------------------------
|mike | 0 | 0 | 0 | 0 | 100 | 0 | 0 |
-------------------------------------------------
|mike | 0 | 0 | 0 | 0 | 0 | 0 | 100 |
-------------------------------------------------
any help or suggestions would be appreciated.
Sounds like you're looking to PIVOT
your results. This should work using SUM
with CASE
:
SELECT `user_name`,
SUM(CASE WHEN DAYOFWEEK(Date) = 1 THEN order_value ELSE 0 END) Sun,
SUM(CASE WHEN DAYOFWEEK(Date) = 2 THEN order_value ELSE 0 END) Mon,
...
SUM(CASE WHEN DAYOFWEEK(Date) = 7 THEN order_value END) Sat
FROM `my_table`
WHERE WEEK(Date) = $thisweek -1 AND YEAR(Date) = $currentYear
GROUP BY user_name
The other answer is good here, and I think you should implement it, but I will make a further recommendation that you run some sort of scheduled process to do it automatically for you, if this is a large data set, or otherwise requires any sort of performance.
What you are doing is a very clear case for storing a denormalized copy of all the data for reporting purposes.
For you, it may be as simple as creating a table that is exactly the same as your output needed here, so you can just do a Select *
type of query on it instead of pivoting. Your needs may vary, but if you find yourself in performance trouble, you should consider it.