Why won't MySQL add these columns up? - mysql

I have a reasonably complex query, that I've simplified down here to try and make it understandable.
In the example below, I am trying to obtain a SUM of sales for two different products. When I retrieve the SUMs individually, as per the first two columns, they calculate correctly.
However, when adding the two SUM queries together (in the third column), if product Y has been sold but NOT product X, the value returns as completely blank.
Any ideas why this might be?
SELECT
(
SELECT SUM(IFNULL(product_x_sales.price, 0))
FROM sales AS product_x_sales
GROUP BY product_x_sales.customer_id
) AS "Total Sales of Product X",
SUM(IFNULL(product_y_sales.price, 0)) AS "Total Sales of Product Y",
(
SELECT SUM(IFNULL(product_x_sales.price, 0))
FROM sales AS product_x_sales
GROUP BY product_x_sales.customer_id
) + (
SUM(IFNULL(product_y_sales.price, 0))
) AS "Total Sales of Products X and Y"
FROM customers
JOIN sales AS product_y_sales ON customers.id = product_y_sales.customer_id
GROUP BY agents.id

When X has no sales, the result of your select would be NULL.
Adding NULL to sales of Y will result in NULL.
SELECT SUM(IFNULL(product_x_sales.price, 0)) <-- = NULL
Change it to this instead
SELECT IFNULL(SUM(IFNULL(product_x_sales.price, 0)), 0)

Related

how can i make query with couple of profits?

first ,i need to get the sum of TotalPrice of sport's and music's departments from the first 3 months of 2016,second, i need to get the result of what i wrote before dividing to sum of all TotalPrice at the year of 2016 from all departments, and third- i need to get the first result dividing to sum of all Total price from all over the years.
all this at the same query!
thanks!
the table called Sales and the attributes are: S_id, date, department, totalPrice.
THIS IS MY CHRY :
Select sum(TotalPrice) as sportMusic, sportMusic/sum(TotalPrice)
From Sales
Where (Department="MUSIC" OR Department="SPORT") and
DATE BETWEEN "2016/01/01" AND "2016/03/31"
You can use your query and two more queries as subqueries (also called "derived tables") in your from clause. Cross join the three result rows and use the totals in your select clause. Something along the lines of:
select
ms_2016_q1.total as ms_2016_q1_total,
ms_2016_q1.total / all_2016.total as rate_2016,
ms_2016_q1.total / all_years.total as rate_all
from
(
select sum(totalprice) as total
from sales
where department in ('MUSIC', 'SPORT')
and date between date '2016-01-01' and date '2016-03-31'
) ms_2016_q1
cross join
(
select sum(totalprice) as total
from sales
where date between date '2016-01-01' and date '2016-12-31'
) all_2016
cross join
(
select sum(totalprice) as total
from sales
) all_years;

Calculating the sum of quantity * unit price in mysql

I think I'm missing a simple step here but I can't seem to figure it out. I've read the other threads and they talk about grouping but I can't seem to put it all together right.
I have a simple table that holds inventory transactions. In each row, there is a quantity and a price. I want to get the sum of the quantity and the sum of the each price * each quantity.
Here's my query. If I remove the grouping, I get 1 result that is multiplied by the number of rows in the table. If I add the grouping, I get the correct result multiple times. Am I missing something here? I just feel like running a query to get 20k results when they all contain the same data would be pointless.
SELECT (SUM(i.quantity) - IFNULL(SUM(s.quantity), 0)) AS quantity,
SUM(i.unitprice * i.quantity) AS totalprice
FROM 02_01_transactions t
LEFT JOIN 02_01_transactions i
ON i.type = 1
AND i.active = 1
LEFT JOIN 02_01_transactions s
ON s.type = 2
AND s.active =1
GROUP BY t.id
Not sure there is a need for the joins (you are not joining on any common value) or the type = 2 rows if you are just subtracting them out. Is there a reason the following does not work?
-- Total quantity, total price of all type 1, active transactions.
SELECT SUM(quantity) AS quantity,
SUM(unitprice * quantity) AS totalprice
FROM 02_01_transactions
WHERE type = 1
AND active = 1
Here's my guess at what you were trying to accomplish:
select
sum(quantity * case type when 1 then 1 when 2 then -1 end) as quantity,
sum(unitprice * quantity) as totalprice
from 02_01_transactions
where type in (1, 2) and active = 1

SQL Average of Sum of Calculated Attribute

I am trying to take the average of the values for a category, where the rows are grouped by sub-category with a calculated sum. The Primary key of the Parent Table is the grouped attribute of the Child Table. The grouped attribute of the Parent Table is neither the primary key or in the Child Table.
Simple representation:
select Category, avg(CalculatedSum)
from ParentTable pt
inner join (
select Subcategory, sum(Quantity * Price) as 'CalculatedSum'
from ChildTable
group by Subcategory
) ct
on pt.ID = ct.Subcategory
group by Category
The actual SQL is as follows:
select c.CU_AGE_RANGE, count(*) as '# of Customers', avg(SumSales) as 'Avg of SumSales', max([Max of SumSales]) as 'Max of SumSales', min([Min of SumSales]) as 'Min of SumSales'
from Customers c
inner join (
select CUSTOMER_ID, sum(QTY_SOLD * SALES) as SumSales, max(QTY_SOLD*SALES) as 'Max of SumSales', min(QTY_SOLD*SALES) as 'Min of SumSales'
from Sales
where (SALES > 0) and (QTY_SOLD > 0) and (COST > 0)
Group by CUSTOMER_ID
) s
on c.CUSTOMER_ID = s.CUSTOMER_ID
group by c.CU_AGE_RANGE
I have tried changing the group by clause to various orders of the Category (CU_AGE_RANGE) and Subcategory (CUSTOMER_ID) but am always having the same error.
The error is that the table will always show me the SUM of the SUMS (I believe). I am assuming this is the error because the typical average in the Child Table is 250 to 1000, and the Avg(Sum()) is returning values that are roughly the number of rows per Category times the expected Sum().
I cannot post a photo due to low reputation, so please see the following Comma Delimited Results Table:
CU_AGE_RANGE,#_of_Customers,Avg_of_SumSales,Max_of_SumSales,Min_of_SumSales
NULL,125,4261665.306,433460737.7,0.0017
20-29 ,1192,1154040.907,1374037708,0.00025
30-39 ,1902,25429.52329,29426212.64,0.00015
40-49 ,2118,2418.829874,2066725,0.0001
50-59 ,2204,114625.4111,248240261.3,0.00015
60+ ,2135,160156.4341,334617675,0.0005
patrickbig,1,65.5737,12,0.06
Under 19 ,484,1431.262112,92160,0.0001
I am trying to figure out why the AVG(SUM()) is returning what seems to be the SUM(SUM()). My current hunch is that since the SUM() is of a calculated entry, the calculated value is recalculated based on the grouping in the Parent Table. So this would be:
DESIRED:
x * y for each row in Child Table
sum(x*y) for each Subcategory
Avg(sum(x/y)) for each Category of Subcategory
QTY_SOLD * SALE for each row in Sales
sum(QTY_SOLD*SALE) for each CUSTOMER_ID
avg(sum(QTY_SOLD*SALE) for each CU_AGE_RANGE group of CUSTOMER_IDs
ACTUAL:
x * y for each row in Child Table
sum(x * y) for each Subcategory
avg(sum(x * y) for each Category
avg(sum(QTY_SOLD*SALE) for each CU_AGE_RANGE
which is equal to:
sum(QTY_SOLD*SALE) for each CU_AGE_RANGE
How do I get from the current (sum of Category) to desired (avg by Category of sum of Subcategory)?
Your count of customers is wrong. You are counting the number of sales made, not the number of customers. Change to count( DISTINCT c.CUSTOMER_ID ) should solve it.
select c.CU_AGE_RANGE, count( DISTINCT c.CUSTOMER_ID ) as '# of Customers', avg(SumSales) as 'Avg of SumSales', max([Max of SumSales]) as 'Max of SumSales', min([Min of SumSales]) as 'Min of SumSales'
from Customers c
inner join (
select CUSTOMER_ID, sum(QTY_SOLD * SALES) as SumSales, max(QTY_SOLD*SALES) as 'Max of SumSales', min(QTY_SOLD*SALES) as 'Min of SumSales'
from Sales
where (SALES > 0) and (QTY_SOLD > 0) and (COST > 0)
Group by CUSTOMER_ID
) s
on c.CUSTOMER_ID = s.CUSTOMER_ID
group by c.CU_AGE_RANGE
Let's think about the sub-query first:
select Subcategory, sum(Quantity * Price) as 'CalculatedSum'
from ChildTable
group by Subcategory
Each and every record of the resulting relation is representing an aggregation of a Subcategory. Now, avg(CalculatedSum) should yield the average of the CalculatedSum values. Try to calculate sum(CalculatedSum) instead and see if there is a difference.

Return the total amount of calculated items in a list

I have a table with Quantity and Price
In the form, beyond these fields, I have the Total = [Quantity] * [Price]
Moreover, the main form I have SomaTotal = Sum([Total])
Ie, the classical sum price that everyone can do.
question:
How do I put this in a full list of Sales?
Ie I have this total for each sale, but I needed a list to return me all sales, and the total of each.
I would have to do a nested query?
The picture is illustrative. I need this list in MS Access.
If I understand you correctly:
SELECT
SUM (SalesSales) AS E1
FROM
Table1
WHERE
(Customer = 1)
UNION ALL
SELECT
SUM (SalesSales) AS E1
FROM
Table1
WHERE
(Customer = 2)
UNION ALL
SELECT
SUM (SalesSales) AS E1
FROM
Table1
WHERE
(Customer = 3)

In a product database, How to calculate pricechange from two periods, and group by category

hi have a product database which the price is changing every month (period) - I want to show the price-change in percent, grouped by category. The schema is something like this: id, name, category, price, period. (The period is YYYY-MM)
A rows could be:
123, "Chair" , "Furniture", 123 , 2013-05 -- for may
123, "Chair" , "Furniture", 110 , 2013-06 -- for june
Is it possible in a SQL-query to calculate the percentage difference for each product for each month? And at the same time group categories together?
The challenge in this sort of query is finding the previous period. Here is one approach:
select p.*,
(p.price -
(select p2.price
from product p2
where p2.id = p.id and p2.period < p.period
order by period desc
limit 1
) - 1
) * 100 as PercentageChange
from product p
order by category;
It uses a correlated subquery and it makes the assumption that there is a price by every month. By "group categories together", I assume you mean to sort by the category. (Aggregating by the category would lose the information about each product.)
Note that the above syntax could vary by database. Different databases have different way of limiting the results to one row.