Mysql sql query to format a report - mysql

This is my table product_details:
Product_Code | Size | Quantity
-------------+------+-----------
CS01 | 10 | 15
CS01 | 11 | 25
CS01 | 12 | 35
PR01 | 40 | 50
PR01 | 41 | 60
I want a the following format for a report to get the total quantity group by product code (all sizes of product code):
Product_Code | Size | Quantity
-------------+------------+----------------
CS01 | 10 11 12 | 75
PR01 | 40 41 | 110
I tried the following query but it does not give the result I want.
SELECT product_no, size, SUM(quantity)
FROM product_details
GROUP BY product_no;
Please help me to find the query to format the report.

You can use group concat
SELECT
product_no,
group_concat(size SEPARATOR ' '),
sum(quantity)
FROM product_details group by product_no;

Related

SQL WHERE function filter-unexpected answer

The problem looks like this:
Write an SQL query that selects the product id, year, quantity, and price for the first year of every product sold.
Return the resulting table in any order.
A simple example of the question:
Input:
Sales table:
+---------+------------+------+----------+-------+
| sale_id | product_id | year | quantity | price |
+---------+------------+------+----------+-------+
| 1 | 100 | 2008 | 10 | 5000 |
| 2 | 100 | 2009 | 12 | 5000 |
| 7 | 200 | 2011 | 15 | 9000 |
+---------+------------+------+----------+-------+
Product table:
+------------+--------------+
| product_id | product_name |
+------------+--------------+
| 100 | Nokia |
| 200 | Apple |
| 300 | Samsung |
+------------+--------------+
Output:
+------------+------------+----------+-------+
| product_id | first_year | quantity | price |
+------------+------------+----------+-------+
| 100 | 2008 | 10 | 5000 |
| 200 | 2011 | 15 | 9000 |
+------------+------------+----------+-------+
My code:
SELECT product_id, year AS first_year, quantity, price
FROM Sales
WHERE year IN (
SELECT MIN(year) as year
FROM Sales
GROUP BY product_id) ;
My code worked with the above simple example but failed on a longer test case.
The expected query:
SELECT product_id, year AS first_year, quantity, price
FROM Sales
WHERE (product_id, year) IN (
SELECT product_id, MIN(year) as year
FROM Sales
GROUP BY product_id) ;
So I don't understand why I have to put productid when filtering with where. Doesn't SQL automatically choose the corresponding product_id with the first year? Any hints would be greatly appreciated!
Here's a step-by-step of why the first query doesn't work. Note that I've omitted some fields that are unused for the sake of brevity.
Imagine your sales data contained the following data:
product_id
year
100
2008
100
2011
100
2011
100
2011
100
2011
200
2011
Based on this data, the inner subquery of your first query:
SELECT MIN(year) as year
FROM Sales
GROUP BY product_id
will produce a result as follows:
MIN(year)
2008
2011
And so then your query is effectively doing the following:
SELECT product_id, year AS first_year
FROM Sales
WHERE year IN (2008, 2011)
So this query is going to find all the sales that occurred in 2008 and all the sales that occurred in 2011. It is not going to filter by product_id as that is not specified in the WHERE statement. So it'll yield results as follows which is not what you want:
product_id
first_year
100
2008
100
2011
100
2011
100
2011
100
2011
200
2011
This is why you need to specify the product_id in your IN statement.
On a general note, when debugging SQL, evaluate the inner-most queries first and then work outward as I have done in this answer.

MySQL SUM only if one of the columns contain a certain value

Is there a way to sum rows only when one of the columns has a certain value? I have this table:
| order_id | total | is_tip |
-----------------------------
| 1 | 12 | 1 |
| 1 | 3 | 0 |
| 2 | 28 | 0 |
| 2 | 15 | 0 |
| 3 | 39 | 1 |
| 3 | 8 | 1 |
The desired result would be:
| order_id | SUM(total) |
-------------------------
| 1 | 15 |
| 3 | 47 |
It would only sum up if one of the is_tip columns is equal to 1. So order IDs 1 and 3 are qualified. So far I've tried to use this query:
SELECT order_id, SUM(total) FROM orders HAVING COUNT(is_tip) >= 1;
But this query is so wrong. I'm just a beginner. Thank you in advance.
Use a having clause:
SELECT order_id, SUM(total)
FROM orders
GROUP BY order_id
HAVING SUM(is_tip) >= 1;
Your query also needs a GROUP BY. And I'm assuming you want a row with at least one "tip". You can also phrase the HAVING clause as:
HAVING MAX(is_tip) > 0
Please use below query,
SELECT order_id, SUM(total) FROM orders where is_tip >= 1 group by order_id;
Having can be used only where you want to filter on aggregation basis

Group Concat in mysql statement

I've got a table called delitems with some colums.
Within my SELECT statement I want to use a GROUP_CONCAT:
+-------------------------------+-------+--------+--------+-----+
| COLOR | tOTAL | Ptotal | Amount | qty |
+-------------------------------+-------+--------+--------+-----+
| BLUE - W = 55,BLUE - W/O = 93 | 148 | 375 | 55500 | 2 |
+-------------------------------+-------+--------+--------+-----+
mysql>select GROUP_CONCAT(color,' = ',qty) as COLOR, SUM(qTY) AS tOTAL, suM(p_cost) as Ptotal, SUM(qty)*SUM(p_cost) as Amount,count(*) qty from delitems where status='3' Group By cont_no;
Everything works fine except the Amount column. The total amount is wrong! Here the correct value:
+-----------------+-------+--------+--------+-----+
| COLOR | tOTAL | Ptotal | Amount | qty |
+-----------------+-------+--------+--------+-----+
| BLUE - W = 55 | 55 | 125 | 6875 | 1 |
| BLUE - W/O = 93 | 93 | 250 | 23250 | 1 |
+-----------------+-------+--------+--------+-----+
mysql>select GROUP_CONCAT(color,' = ',qty) as COLOR, SUM(qTY) AS tOTAL, suM(p_cost) as Ptotal, SUM(qty)*SUM(p_cost) as Amount,count(*) qty from delitems where status='3' Group By color;
I only want to display it in one line with the correct total amount
Please help.
Should be you need sum(a*b) not sum(a)*sum(b)
select
GROUP_CONCAT(color,' = ',qty) as COLOR
, SUM(qTY) AS tOTAL
, suM(p_cost) as Ptotal
, SUM(qty*(p_cost) as Amount, count(*) qty
from delitems
where status='3' Group By cont_no;

How to SUM Row values and save the result in a new Total Column?

I need to calculate the sum of stock from some rows, the same product exist for different companies, so I need to calculate the SUM/Total of all products, per product name, this is the result that I want to achieve:
ID | Name | Company | Stock | Total Stock
1 | Product1 | Company1| 10 | 30
2 | Product1 | Company2| 10 | 30
3 | Product1 | Company2| 10 | 30
4 | Product2 | Company1| 10 | 15
5 | Product2 | Company2| 5 | 15
6 | Product3 | Company2| 5 | 5
7 | Product4 | Company1| 6 | 10
8 | Product4 | Company2| 4 | 10
Etc...
The Total Stock is the sum of Select SUM(Stock) From Product Where Name="Product1"
How can I save this result ? Should I use a Trigger Or a Procedure? I have basic knowledge of SQL
This needs to run every 30 minutes or every time a row is updated.
The product table has around 40.000 Products.
SELECT a.*, b.totalStock
FROM tableName a
INNER JOIN
(
SELECT Name, SUM(Stock) totalStock
FROM tableName
GROUP BY Name
) b on a.name = b.name
-- WHERE a.Name = 'Product1'
SQLFiddle Demo
PS: you need to use ID instead of Name.

Count columns according to dates in SQL

I need help with a SQL statement. The goal is to count the amount of alarms of each date. My table looks something like this:
|----DATE----|---COUNTER---|---ALARM_ID---|
|2012-01-01 | 30 | 1 |
|2012-01-01 | 20 | 2 |
|2012-01-01 | 10 | 3 |
|2012-01-02 | 5 | 1 |
|2012-01-02 | 25 | 2 |
|2012-01-02 | 12 | 3 |
|2012-01-03 | 33 | 1 |
|2012-01-03 | 43 | 2 |
|2012-01-03 | 11 | 3 |
And I'm looking for a SQL statement that gives this result:
|----DATE----|---COUNTER---|
|2012-01-01 | 60 |
|2012-01-02 | 42 |
|2012-01-03 | 87 |
I've been working on this SELECT date, SUM(counter) FROM all_stats but all I get is:
|----DATE----|---COUNTER---|
|2012-01-01 | 60 |
Do I have to create a loop to go through all dates and count?
Thanks in advance, Steve-O
SELECT date, SUM(counter)
FROM all_stats
GROUP BY date
Try this instead
SELECT date, SUM(counter) FROM all_stats GROUP BY date;
"GROUP BY date" puts all the individual dates on a separate line and does the sum separately per date.
select date, sum(counter)
from all_stats
group by date