SQL Selecting multiple sums? - sql

Let's say I have a table:
SELECT SUM(quantity) AS items_sold_since_date,
product_ID
FROM Sales
WHERE order_date >= '01/01/09'
GROUP BY product_ID
This returns a list of products with the quantity sold since a particular date. Is there a way to select not only this sum, but ALSO the sum WITHOUT the where condition? I'd like to see sales since a particular date for each product alongside all (not date limited) sales.

SELECT SUM(CASE WHEN order_date >= '01/01/09' THEN quantity ELSE 0 END) AS items_sold_since_date,
SUM(quantity) AS items_sold_total,
product_ID
FROM Sales
GROUP BY product_ID

something like this?:
SELECT SUM(quantity) AS items_sold_since_date,
total_items_sold = (SELECT SUM(quantity) from Sales GROUP BY product_ID),
product_ID
FROM Sales
WHERE order_date >= '01/01/09'
GROUP BY product_ID

If you like to see total sales alongside, then you would use sum(sale_amt), and in the group by add the sale_amt. I hope it helps.

You could use GROUP BY to split up the Sales based on date.
In Oracle you could say:
select count(*)
,case when order_date >= '01/01/09' then 'after' else 'before' end
from log
group by case when order_date >= '01/01/09' then 'after' else 'before' end;

you can write
SELECT SUM(quantity) AS items_sold_since_date,(SELECT SUM(quantity) AS items_sold_since_date FROM Sales
GROUP BY product_ID) as items_sold,
product_ID
FROM Sales
WHERE order_date >= '01/01/09'
GROUP BY product_ID

Related

Execution orders of SQL aggregate functions

I have a sales table in SQLite:
purchase_date
units_sold
customer_id
15
1
1
17
1
1
30
3
1
I want to get the total unit_solds for each customer on the first date and last date of their purchases. My query is:
select customer_id,
sum(units_sold) total_units_sold
from sales
group by customer_id
having purchase_date = min(purchase_date)
or purchase_date = max(purchase_date)
I was expecting results like:
customer_id
total_units_sold
1
4
but I got:
customer_id
total_units_sold
1
5
I would like to know why this solution doesn't work.
The order of the phrase is incorrect
Note: The having statement is executed after compilation.
You need to get the results as partial queries
For example, I arranged to know the first line of the date according to each customer
as well as the last line of the date (by getting the first line after descending order)
and then execute the group statement
The example is complete
select customer_id,sum(units_sold) from (
select customer_id, units_sold,purchase_date,
ROW_NUMBER() over(partition by customer_id order by purchase_date) As RowDatefirst,
ROW_NUMBER() over(partition by customer_id order by purchase_date desc)As RowDatelast
from sales
) t where t.RowDatefirst = 1 or t.RowDatelast=1
group by customer_id
Try this:
SELECT a.customer_id, SUM(a.units_sold) as total_units_sold
FROM sales a
INNER JOIN (
SELECT customer_id, MIN(purchase_date) as _first ,MAX(purchase_date) as _last
FROM sales
GROUP BY customer_id
) b ON a.customer_id = b.customer_id AND
(a.purchase_date = b._first OR a.purchase_date = b._last)
GROUP BY a.customer_id
http://sqlfiddle.com/#!7/0a4a4/7

How to get the asked columns for each customers

I have this table called table a
I need to get the CustomerID, sum(Income) of 2015, sum(Income) of 2016, did he ever bought productId A (boolean), is the total sum(income)> 1000 (boolean), number of total InvoiceID
all that in one query and the results should be with 1 row per customer.
please help I don't even know how to start!
This is basically conditional aggregation:
select customerid,
sum(case when extract(year from date) = 2015 then sales end) as sales_2015,
sum(case when extract(year from date) = 2016 then sales end) as sales_2016,
max( product = 'A' ) as ever_bought_a,
sum(income) > 1000 as sum_exceeds_1000,
count(*) as num_invoices
from t
group by customerid;
You haven't specified a database, so this is really psuedocode. You'll need to adapt it for your particular database.

SQL: Looking at Bundle of Products Sold

I have a sample DB below. I'm looking to see how many TV and Internet bundles we sold. In the sample data, only Bob and Trevor sold that bundle so we sold 2.
How do I write the query for the number of bundles sold by each Sales rep and the total price of the bundles sold?
Thanks
I imagine that, for a bundle to happen, the same sales person needs to have sold both products to the same customer.
I would approach this with two levels of aggregation. First group by sales person and customer in a subquery to identify the bundles, then, in an outer query, count how many such bundles happened for each sales person:
SELECT sales_person, COUNT(*) bundles_sold, SUM(total_price) total_price
FROM (
SELECT sales_person, customer_name, SUM(total_price) total_price
FROM mytable
WHERE product_name in ('TV', 'Phone')
GROUP BY sales_person
HAVING COUNT(DISTINCT product_name) = 2
) x
You can simply group the salesman's by counting the distinct products they sold -
SELECT Sales_Person, FLOOR(COUNT(DISTINCT product_name)/2) NO_OF_BUNDLES, sum(total_price)
FROM YOUR_TAB
WHERE product_name IN ('TV', 'Internet')
GROUP BY Sales_Person
HAVING COUNT(DISTINCT product_name) >= 2
Using cte as below:
with cte1(sales_person, customer_name, product_count) as
(
select sales_person, customer_name, count(product_name)
from sales
where product_name in ('TV', 'Internet')
group by sales_person, customer_name
having count(product_name) = 2
)
select sales_person, count(product_count)
from cte1
group by sales_person
I would suggest two levels of aggregation:
select sales_person, count(*), sum(total_price)
from (select sales_person, customer_name,
sum(total_price) as total_price,
max(case when product_name = 'tv' then 1 else 0 end) as has_tv,
max(case when product_name = 'phone' then 1 else 0 end) as has_phone,
max(case when product_name = 'internet' then 1 else 0 end) as has_internet
from t
group by sales_person, customer_name
) sc
where has_phone = 0 and
has_tv = 1 and
has_internet = 1
group by sales_person;
I recommend this structure because it is pretty easy to change the conditions in the where clause to return this for any bundle -- or even to aggregate by the three flags and return the totals for all bundles in one query.

How to get the last sold price in SQL

I am working on a query that will show me basic item information as well as the total qty shipped (for all orders),last date that the item was sold and the price it was sold at. I cant figure out how to get the last sold price. This is what I have so far,
SELECT
item_id
,item_desc
,sum(qty_shipped) AS 'Total Qty Shipped'
,count(item_id) AS 'No of times Shipped'
,max(invoice_date) AS 'Last Invoice_date'
,unit_price AS 'Last Price'
FROM sales_history_report
WHERE
item_id = '1234'
AND year_for_period >= '2017'
AND sales_location_id like '10'
GROUP BY
item_id
,item_desc
,unit_price
with this query I am getting all of the lines that this item is on. It looks like this right now,
Item_id,Item_desc,Total_QTY_shipped,no_of_times_shipped,Last_Invoice_date,Last_price
1234,Item 1234,4,1,2014-10-15,2.47
1234,Item 1234,6,1,2014-09-20,2.519
But I am looking for
Item_id,Item_desc,Total_QTY_shipped,no_of_times_shipped,Last_Invoice_date,Last_price
1234,Item 1234,10,2,2014-10-15,2.47
Any help would be appreciated.
If I understand correctly, you can use conditional aggregation:
select item_id, item_desc,
sum(qty_shipped) as [Total Qty Shipped],
count(item_id) as [No of times Shipped],
max(invoice_date) as Max_Date,
max(case when seqnum = 1 then unit_price end) as [Last Price],
from (select shr.*,
row_number() over (partition by item_id order by invoice_date desc) as seqnum
from sales_history_report shr
) shr
where item_id = 1234 and
year_for_period >= 2017 and
sales_location_id like '10'
group by item_id, item_desc;
Comments:
Do not use single quotes for column aliases. Only use single quotes for string and date constants.
The columns in the GROUP BY define the rows in the result set. I don't think you want unit_price in it.
Do not use single quotes for numeric constants. I assume item_id an the year are numeric.

Working out total from sub total and amount

I have a table with purchased orders data.
Each row contails the amount of certain item purchased, cost per item and the order number group. Each different item purchased is a new row with same order number.
I basically want to return the total cost for that order. I have tried the following but am getting nowhere:
SELECT order_number, SUM( sub_total ) AS `total`
FROM
SELECT order_number, SUM( SUM( amount ) * SUM( cost_per_item ) ) AS `sub_total`
FROM `ecom_orders`
WHERE member_id = '4'
GROUP BY order_number
ORDER BY purchase_date DESC
Pretty much any SQL-92 compliant RDBMS will take this:
SELECT
order_number
,SUM(amount * cost_per_item) AS total
,purchase_date
FROM
ecom_orders
WHERE member_id = '4'
GROUP BY order_number,purchase_date
ORDER BY purchase_date DESC