Create line chart using value from SQL database - php

So I've been following this tutorial: https://www.plus2net.com/php_tutorial/chart-line-database.php
I am trying to add a line chart to my website to display number of sales for each month.
This is an example on how my SQL table looks like:
| ID | user | sale_id | date |
| 1 | RVN4372 | 1341234 | 2020-09-22 17:31:32 |
| 2 | OVI6517 | 5452351 | 2020-09-22 15:14:43 |
| 3 | RVN4372 | 8452176 | 2020-09-17 16:23:54 |
| 4 | FOK8905 | 7421312 | 2020-09-17 11:23:11 |
| 5 | DIF9127 | 4236123 | 2020-09-15 15:32:26 |
This is how my current query looks like:
<?php
if($stmt = $link->query("SELECT user,COUNT(*) FROM sales WHERE yearweek(DATE(date), 1) = yearweek(curdate(), 1) GROUP BY user order by COUNT(*) DESC")){
$php_data_array = Array(); // create PHP array
while ($row = $stmt->fetch_row()) {
$php_data_array[] = $row; // Adding to array
}
}else{
echo $link->error;
}
//print_r( $php_data_array);
// You can display the json_encode output here.
echo json_encode($php_data_array);
// Transfor PHP array to JavaScript two dimensional array
echo "<script>
var my_2d = ".json_encode($php_data_array)."
</script>";
?>
<div id="curve_chart"></div>
This is how it looks like on my website:
So this basically groups the users, and count how many sales each user has. On the X axis is display the user's name, and Y axis total number of sales.
I want to change this, so in the X asix is display the month, and Y asis total number of sales. How can I accomplish this?
EDIT: Hava been trying out some, but can't make it work. This is what I've got so far:
if($stmt = $link->query("
SELECT YEAR(date)
as SalesYear,
MONTH(date) as SalesMonth,
COUNT(*) AS TotalSales
FROM sales
GROUP BY YEAR(date), MONTH(date)
ORDER BY YEAR(date), MONTH(date)
AND COUNT(*) DESC
")){

If you have more than one year then you need to group in Year-month combination. Then change this query to this.
SELECT CONCAT(YEAR(date),'-' MONTHNAME(date)) as ym, COUNT(*) FROM sales GROUP BY ym ORDER BY count(*) DESC

Related

SQL Query count rows where multiple column-values

So this is a how my MySQL table looks like (I have many thousands of rows):
| ID | date | Color | IUSERQ |
| 1 | 2020-09-25 18:55:54 | RED | GGW3 |
| 2 | 2020-09-25 18:24:12 | RED | FFQ3 |
| 3 | 2020-09-24 17:32:52 | RED | GWW3 |
| 4 | 2020-09-23 17:42:37 | BLUE | JJN6 |
| 5 | 2020-09-23 17:33:55 | BLUE | VVV5 |
| 6 | 2020-09-23 18:53:57 | RED | FFQ3 |
| 7 | 2020-09-22 18:15:11 | BLUE | FFQ3 |
Now to count all of the rows and group them in weeks, I do this:
if($stmt = $link->query("SELECT WEEK(date),COUNT(*) FROM sales WHERE color='RED' AND YEAR(date) = YEAR(NOW()) GROUP BY WEEK(date) order by MONTH(date) ASC")){
$php_data_array = Array(); // create PHP array
while ($row = $stmt->fetch_row()) {
$php_data_array[] = $row; // Adding to array
}
}else{
echo $link->error;
}
echo json_encode($php_data_array);
On the echo json_encode($php_data_array);, it gives the this current output: [["36","154"],["37","247"],["38","275"]]. So the first string in the array (36, 37, 38) is the week number, and the second one the number of rows where color is RED. Now, I also want to add where color is BLUE in the same array, so the expected value should be something like: [["36","154","166"],["37","247","265"],["38","275","298"]].
What approach should I use to do this?
Just add another column:
SELECT WEEK(date) as week, SUM(color = 'RED') as red, SUM(color = 'BLUE') as blue
FROM sales
WHERE color IN ('RED', 'BLUE') AND YEAR(date) = YEAR(NOW())
GROUP BY WEEK(date)
ORDER BY WEEK(date) ASC;
Note the changes to the query:
The SUM() does conditional aggregation for each color.
The columns are given names, which can be used to reference them in the application.
The ORDER BY is by the column being aggregated.
Use conditional aggregation:
select week(date) week_date, sum(color = 'RED') cnt_red, sum(color = 'BLUE') cnt_blue
from sales
where color in ('RED', 'BLUE') and date >= date_format(current_date, '%Y-%m-01')
group by week(date)
order by week_date
Note that this uses direct filtering on the date column, without applying functions on the filtered column. This is more efficient that year(date) = year(now()), especially if you have an index on that column.
I also changed the order by clause: obviously, you want to order by week rather than month (in most databases, that's a compilation error, because the month does not belong to the group by clause).
You can use dynamic query as another option :
SET #sql = NULL;
SELECT GROUP_CONCAT(
DISTINCT
CONCAT(
'SUM( color =''', color, ''' ) AS ',color
)
)
INTO #sql
FROM sales s;
SET #sql = CONCAT('SELECT WEEK(date) AS WEEK,',#sql,
' FROM sales
WHERE YEAR(date) = YEAR(NOW())
GROUP BY WEEK
ORDER BY WEEK');
and then call from php code block such as :
if($stmt = $link->query( #sql )){ ....
$php_data_array = Array(); // create PHP array
....
This way, no need to add each color name to be grouped individually, the query pivots all color column values whichever exist within the table. New colors might be added or existing ones might be deleted without constructing new querie.
Demo (in order to show result of the query)

How to count row by using GROUP mysql bind_param?

How to count row by using GROUP mysql bind_param ?
Table : check
.
__________________________
| id | product_id | user |
| 1 | 123 | test |
| 2 | 456 | test |
| 3 | 456 | test |
| 4 | 123 | test |
| 5 | 789 | test |
and this is my code
<?PHP
$username = "test";
$sql = 'SELECT COUNT(*) FROM check WHERE user = ? GROUP BY product_id';
$statement = $db_mysqli->prepare($sql);
$statement->bind_param('s', $username);
$statement->execute();
$result = $statement->get_result();
$row = $result->fetch_row();
$all_product = $row[0];
echo $all_product;
?>
When I test code it's show 5 I want to know how can I do for show 3 group by product_id
You need to change your SQL query.
SELECT COUNT(DISTINCT PRODUCT_ID) FROM check WHERE user = ?
this will produce a result of 3
If you wanted one row for each product, then you would do this:
SELECT product_id, COUNT(*) AS c FROM check WHERE user = ? GROUP BY product_id
which would look like this:
| product_id | c |
| 123 | 2 |
| 456 | 2 |
| 789 | 1 |
Try this query.
$statement=$mysqli->prepare("SELECT user,COUNT(*) FROM check GROUP BY product_id");
I hope it will help you.
you can use one of these three queries as per your need. It will give you results as shown below.
To get the total of rows with distinct product_id present in table-:
SELECT COUNT(DISTINCT product_id) FROM check;
Result-:
COUNT(DISTINCT product_id)
3
To get the rows with distinct product_id row-:
SELECT COUNT(DISTINCT product_id) FROM check GROUP BY product_id;
Result-:
COUNT(DISTINCT product_id)
1
1
1
To get the row with distinct product_id with the count number of duplicate product_id present in the table -:
SELECT COUNT(product_id) FROM check GROUP BY product_id
Result-:
COUNT(product_id)
2
2
1

How to do a result and row that will find the sql sum of two columns?

Table 1 Table 2
_________________ ____________________
| ID| Name |Age | | ID| Cost | Date |
|---|-------|----| |---|-------|-------|
| 1 | Kirk | 33 | | 1 | 10 | 9/10 |
| 2 | Lonzo | 55 | | 1 | 20 | 7/8 |
| 3 | Dave | 44 | | 2 | 12 | 25/7 |
| 3 | 5 | 30/4 |
| 3 | 5 | 4/10 |
I want the result to be Kirk, who is 33, has a total cost of 30 and total dates to 2
etc.. (btw they enter their names and all this comes up)
The sql statement would be like this?
$sql= "SELECT Table1.Name, Table1.ID, Table2.ID, Table1.Age, SUM(Table2.Cost), SUM(Table2.Date)
AS count from Table1, Table2
WHERE Table1.ID = Table2.ID and Table1.Name = (my example here)"
$result = $conn->query($sql);
$Cost = 0;
$Date= 0;
$rec = $result->fetch_assoc();
$Date= $rec{'count'};
$Cost= $rec{'count'};
$Age = $rec{'Age'}
echo "$Name, who is $Age years old a total cost of $Cost and $Date total dates";
Im getting errors, saying my variables are undifined
so how would I put them into variables?
EDIT fixed
instead of using the sql to find it, i used result from a while loop that kept adding one to another variable (to count the date). The cost is able to do in both sql(sum) and result.
instead of using the sql to find it, i used result from a while loop that kept adding one to another variable (to count the date). The cost is able to do in both sql(sum) and result.
You were missing a group clause. I also put that in a subquery and used an INNER JOIN
SELECT Id, Name, Age, Cost, Dates
FROM Table1
INNER JOIN (
SELECT Id i, SUM(Cost) Cost,
COUNT(Date) Dates
from Table2
GROUP BY Id) t
ON i=Id
WHERE Name = 'Kirk'
You should also change one of the php statements to
$Cost= $rec{'Cost'};
Just use join..
SELECT table2.date ,SUM(cost) AS tatol FROM table1
JOIN table2 ON table2.id = table1.id
WHERE table1.id = 1

Unable to fetch the accurate rooms availability in specific date range

Here is my database structure
Table name :set_inventory, and columns are below
inventory_id | room_id | quantity_start_date | quantity_end_date | total_rooms
1 | 2 | 2015-10-10 | 2015-10-12 | 5
2 | 2 | 2015-10-13 | 2015-10-14 | 10
3 | 2 | 2015-10-15 | 2015-10-17 | 0
Another Table
Table name : rooms, amd columns are
room_id | room_type | room_picture | room_description
2 | standard | pic_link | demo description
Description: In inventory table admin able to set the inventory based on multiple date ranges.
My query:
SELECT rooms.room_id, rooms.room_pic1, rooms.room_type, rooms.maximum_adults,
rooms.maximum_children, rooms.room_amenities,set_inventory.room_id,
set_inventory.quantity_start_date, set_inventory.quantity_start_date,
set_inventory.total_rooms
from rooms, set_inventory
WHERE rooms.room_id = set_inventory.room_id
AND quantity_start_date <= '2015-10-11'
AND quantity_end_date > '2015-10-13'
It shows me the inventory only 5, based in above query,
What i am looking for :actually, i am looking for the result,
for example my check_in_date "2015-10-11" and check_out_date is "2015-10-17"
In this i will be able to notify the customer that
"room is only available for 4 days,
Plz help me , thanks
UPDATED
Try this WHERE condition:
WHERE rooms.room_id = set_inventory.room_id AND DATE(quantity_start_date) <= '2015-10-11' AND DATE(quantity_end_date) > '2015-10-13';
So, minding you want to have the amount of days between these to dates, your query should contain somwthing like this:
SELECT ABS(DATEDIFF(a1.start_date, a2.end_date)) FROM (
SELECT quantity_start_date as start_date FROM set_inventory WHERE quantity_start_date <= '2015-10-11' ORDER BY start_date DESC LIMIT 1) a1, (
SELECT quantity_end_date as end_date FROM set_inventory WHERE quantity_end_date > '2015-10-13' ORDER BY end_date ASC LIMIT 1) a2;
If you try it, you'll get 4 in result.

Double SQL Query - JOIN

I need a double SELECT sql query from 2 different tables with names visits & items
1.: SELECT visitid, visitdate, visitreason FROM visits WHERE personid = 10
2.: SELECT itemid, itemname, itemtime FROM items WHERE itemvisitid= visitid
I think I need to do a JOIN but don’t know exactly how.
Table examples:
Table: visits
visitid | personid | visitdate | visitreason
1 | 10 | 05/07/2014 | no reason
2 | 10 | 06/07/2014 | some reason
3 | 12 | 06/07/2014 | no reason
4 | 10 | 12/07/2014 | some other reason
Table: items
itemid | personid | itemvisitid | itemname | itemtime
1 | 10 | 2 | box | 23
2 | 10 | 2 | clock | 70
3 | 10 | null | water | 50
4 | 10 | null | paper | 40
5 | 12 | 3 | box | 26
What I have now is this:
$query = "SELECT visitid, visitdate, visitreason FROM visits WHERE personid = '10' ORDER BY visitdate DESC";
// 2nd select: "SELECT itemid, itemname, itemtime FROM items WHERE itemvisitid= visitid";
$db->setQuery($query);
$results = $db->query();
while($row = mysqli_fetch_array($results)){
echo "<tr>
<td>".$row['visitid'].", ".$row['visitdate']."</td>
<td>".$row['visitreason']."</td>
<td>".$row['itemid'].",".$row['itemname'].", ".$row['itemtime']."</td>
</tr>";
}
I need results to be something like this:
<tr>
<td>1, 05/07/2014</td><td>no reason</td><td></td>
<td>2, 06/07/2014</td><td>some reason</td><td>1, box, 23<br />2, clock, 70</td>
<td>4, 12/07/2014</td><td>some other reason</td><td></td>
</tr>
I guess your might to use GROUP_CONCAT like this:
DEMO: http://sqlfiddle.com/#!2/9d4e22/15
SELECT visitid, DATE_FORMAT(visitdate,'%m/%d/%Y'), visitreason,
GROUP_CONCAT(itemid,itemname, itemtime)
FROM visits left join items on visits.visitid = items.itemvisitid
WHERE visits.personid = 10
GROUP BY visitid, visitdate, visitreason
You might want to read this to know GROUP_CONCAT :
How to use GROUP_CONCAT in a CONCAT in MySQL
The document of GROUP_CONCAT() is here:
http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat
hope this helps.
SELECT `visits`.`visitid`, `visits`.`visitdate`, `visits`.`visitreason`,`items`.`itemname`, `items`.`itemtime` from `visits` INNER JOIN `items` ON `visits`.`personid`=`items`.`personid` WHERE `visits`.`personid` = '10' ORDER BY `visits`.`visitdate` DESC
if there is any error please change the field name personid in 'items' table.and then check.
This query:
SELECT v.visitid,
v.visitdate,
v.visitreason,
i.itemid,
i.itemname,
i.itemtime
FROM visits v
INNER JOIN items i
ON ( v.visitid = i.itemvisitid )
WHERE v.person_id = 10
ORDER BY v.visitdate DESC,
i.itemid ASC
will link both tables and produce a resultset that you can traverse using a double loop. The outer loop to process changes to the visit, and the inner to add every item visited in a particular visit.

Categories