I have a groupby and sum table that I use to display current stock (it groups and sums all stock entries). I want to now display the latest entry date for each groupby group.
Here is what I'm working with:
-------------------------------------------------------------------
ProductID | Color | Timestamp | Quantity | RowID |
-------------------------------------------------------------------
25 | Red | 10/10/10 06:22:15 | 250 | 1 |
-------------------------------------------------------------------
32 | Green | 10/10/10 06:23:45 | 100 | 2 |
-------------------------------------------------------------------
$query = "SELECT productid, color, SUM(Quantity) AS TotalQuantity FROM inventory GROUP BY productid, color";
$result = mysql_query($query) or die(mysql_error());
// Table markup here
echo '<tr><td>'. $row['productid'] . '</td><td>' . $row['color']. '</td><td>'. $row['TotalQuantity'];
// Table markup here
I was trying to use the max value function to get the max rowid for each groupby but it was getting so confusing!
Well, if the latest entry date for each group is also by construction the most recent one, you can simply use:
SELECT
productid,
color,
SUM(Quantity) AS TotalQuantity,
MAX(Timestamp) AS LatestDate
FROM inventory
GROUP BY productid, color;
Related
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)
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
I have category table tb_category
categoryid | category_name
1 | New Product
2 | Promo
And I have product table tb_product
productid | product_name | categoryid_fk
1 | Watch | 1
2 | Bag | 1,2
And now I want to get category name from productid = 2 with categoryid_fk = 1,2
How to do that?
My SQL code so far:
//category id --> 1,2
$qCategory = mysqli_query($con, "SELECT * FROM tb_category WHERE categoryid IN ('" . $dProduct['categoryid_fk'] . "')");
foreach($qCategory as $cause)
{
echo $cause['category_name'];
}
When I run the query I only get the category name with single categoryid.
Use find_in_set function. Usage: find_in_set(search_string, list of strings).
See demo here: http://sqlfiddle.com/#!9/4e5a48/1
EDIT: since the requirement is changed, add a replace function to remove spaces so that find_in_set will work.
SELECT tb_category.*
FROM tb_category,tb_product
WHERE find_in_set(categoryid, replace(categoryid_fk,' ','')) > 0
and productid = 2;
Result:
categoryid category_name
1 New Product
2 Promo
enter image description here I am having one table like id, sale_id, item_total, tax fields. need to sum the item_total by grouping the tax values.
Table 1
id | sale_id | item_cost_price | tax |
1 | 10 | 150 | 5 |
2 | 10 | 50 | 7 |
3 | 10 | 30 | 5 |
this is required output:
id | sale_id | item_cost_price | tax |
1 | 10 | 180 | 5 |
2 | 10 | 50 | 7 |
When i tried this query,
SELECT sale_id,tax FROM bgs_ib_sales_items GROUP BY tax
$query=$this->db->query("SELECT sale_id,tax FROM bgs_ib_sales_items GROUP BY tax ");
echo $num = $query->num_rows();
$result=array();
foreach($query->result() as $row){
$result_row[]=$row->sale_id;
$result_row[]=$row->tax;
$result_row[]=$row->item_cost_price;
}
My output is:
i am getting output like this,
am getting distinct tax only. but i need to sum item total values.
Note:
Image 1 : refer my datatable
Image 2: refer my expected outputenter image description here
Add SUM(item_cost_price) in SELECT statement.
In your select statement your select only sale_id, tax. But what you echo are sale_id, tax, and item_cost_price which not exist in your SELECT statement. Try This:-
$sql = "SELECT sale_id,tax, SUM(item_cost_price ) AS TotalPrice FROM bgs_ib_sales_items WHERE sale_id = '10' GROUP BY tax";
$query=$this->db->query($sql);
foreach($query->result() as $row){
$result_row[]=$row->sale_id;
$result_row[]=$row->tax;
$result_row[]=$row->TotalPrice;
}
Hello I am trying to make a Select where the uses chooses department and would like to have clause WHERE this department is first, let's say we select 10 results from department: Taxes and then make a SUM SELECT of fee WHERE status = 1. Which results be selected based on the first select All the results are coming from the same table.
| id | department | status | fee |
----------------------------------
| 1 | tax | 1 | 20 |
| 2 | tax | 2 | 20 |
| 3 | tax | 1 | 20 |
| 4 | accounting | 1 | 20 |
So I would like to select if department is choose as tax, and status is 1 the sum of FEE columns which should be 40
So far my Select query looks like this:
SELECT P.id, P.fee, (SELECT SUM(P.fee) FROM cases P WHERE status = 1) as fee_USD
FROM cases P WHERE 1";
if (!empty($department)) { $sql .= " AND P.department = '$department'"; }
the last line is checking if department is given as select option. there are other options as well but to make it simple I have pasted only this part of it. Any help is welcome.
In the Current Selection Fee is = 80
You have to add correlation to your query:
SELECT P1.id, P1.fee,
(SELECT SUM(P2.fee)
FROM cases P2
WHERE P2.department = P1.department AND status = 1) as fee_USD
FROM cases P1
WHERE 1 ...
This way the subquery will return the SUM of only those records which are related to the current record of the main query.