SQL Server: How to calculate different sums in a single query - sql

A friend has suggested I post here as I'm in need of a bit of help!
DB Layout:
**salestable**
salesorder [primary, unique] (sales order number)
salesman (salesperson id)
**salesline**
salesorder [many sales line to single salestable relationship]
saleprice (line amount)
isaccessory (0 or 1)
I'd like to, in a single select, sum sales price as a total per salesman, but also sum sales price where is accessory = 1.
The grouping and joins aren't what I'm stuck on, it's whether I can do the dual sum.
In my head it would look something like
...salesman,sum(amount) as totalsales,sum(amount where accessory=1) as accessorysales...
But obviously that would never work!
Thanks in advance! (PS, I'm very new here, be gentle...)

SELECT salesman, SUM(amount), SUM(CASE WHEN accessory = 1 THEN amount ELSE 0 END)
FROM salestable t
JOIN salesorder o
ON o.salesorder = t.salesorder
GROUP BY
salesman

Related

I would like to show the TotalSales by Single Column but I would like to show another 2 columns in the output

I have a table like below and I would like to show TotalSales based on Category column.
Category
Sub-Cate
Sales
Chairs
Paper
16.448
Suppliers
Binders
3.54
Chairs
Art
85
Suppliers
Binders
45.89
Furniture
Paper
75.235
I'm trying to use this query:
select Category,sales,TotalSales from (
select Category,Sales,
case when Category='Office Supplies' then sum(sales)
when Category='Furniture' then sum(sales)
end as TotalSales
from Orders$
group by Category,Sales ) as tmp
order by Category desc
I would like to show as below.
Category
Sub-Cate
Sales
TotalSales
Percentage
Chairs
Paper
16.448
101.448
%
Suppliers
Binders
3.54
49.43
%
Chairs
Art
85
101.448
%
Suppliers
Binders
45.89
49.43
%
Furniture
Paper
75.235
75.235
%
can anyone help to get this query.
Note: Percentage= Sales/Sub-Cate Total Sales
If i understand correctly you need this, hope it helps :
Let's assume that your table name is TableName.
Select tn.Category,
tn.Sub_Cate,
tn.Sales,
tn1.TotalSales,
((tn.Sales * 100) / tn1.TotalSales) PercOfTotal
from TableName Tn
join (Select category,
sum(Sales) TotalSales
from TableName Tn1
group by 1
) tn1 on tn1.category = tn.category
order by 1,2,3
In the immortal words of Tom Kyte, the Oracle grandmaster who launched "Ask Tom", "analytics rock, analytics roll."
Analytics is another name for window functions. What the windows function gives you is the ability to compute some aggregate function like sum() but make it available to every row in the group.
create table sales(category varchar,subcate varchar,sales float);
insert into sales values ('Chairs','Paper',16.448);
insert into sales values ('Chairs','Art',85);
insert into sales values('Suppliers','Binders',3.54);
insert into sales values('Suppliers','Binders',45.89);
insert into sales values('Furniture','Paper',75.235);
Now according to your question we need the total sales for each category and use it to create a percentage for each row (different subcate).
The sum() window function works perfectly for that. The "partition by" column or columns if you need more than one, are the columns you would group by in order to get your sum, but doing it this way gives you that sum associated for each row
select
category,
subcate,sales,
sum(sales) over (partition by category) totalSales,
100*sales/sum(sales) over (partition by category) pct
from sales;

SQL Calculate Sale Closure Percentage Rate Per Sales Person For Regions A and B

I have a dataset (sales_dataset) where each row represents a sales attempt, and there are 3 columns showing the sales person (sales_person), region (region), and whether the attempt was successful or not (sale). The table can be seen here:
I am trying to calculate the percentage of successful sales grouped by each sales person for regions A and B but I can't seem to figure out how to do so i.e. I am trying to find (successful sales / total sales) for each sales_person for regions A and B. You can see an image of what I am trying to generate here:
The furthest I've gotten so far is to generate a count of succesful sales for each sales person, with the following query:
SELECT sales_person, Count(sale) as "Sales Rate %"
FROM sales_dataset
Where sale = "Sale" AND region = "A" OR "B"
Group By sales_person
Thanks!
You can use avg():
select sales_person,
avg(case when sale = 'Sale' then 1.0 else 0 end) as sales_rate
from sales_dataset
where region in ('A', 'B')
group by sales_person;

getting avg of column based on the result set

I have a select statement that divides the count of sales by country, priceBanding (see example below)
The select statement looks like follows:
SELECT p.[Price Band]
,t.[Country]
,o.COUNT([Order]) as [Order Count]
FROM #price p (temp table)
INNER JOIN country t ON p.CountryCode = t.countryCode
INNER JOIN sales o ON o.salesValue >= p.startPrice and s.salesValue < p.endPrice
What i want to be able to do is based on this result i want to get an avg of the unit count i.e. For all orders that are under 20 what is the avg unit counts and the same for all others. How can i do this?
Its most likely simple but I cant think through it.
What I am after:
So as you can see, in the price band <20 in UK the order count is 50, and the avg Units of that is 2. As i mentioned earlier, I want the Avg Units of all orders that are under 20 (which is 50 in the picture).
Is that clearer?
Thanks in advance.
EDIT:
The first table: assume it to be the source
And the second table gets the avg, that's what I am after.
Wouldn't you just use avg()?
SELECT p.[Price Band], t.[Country],
o.COUNT(*) as [Order Count],
AVG(Items)
FROM #price p INNER JOIN
country t
ON p.CountryCode = t.countryCode INNER JOIN
sales o
ON o.salesValue >= p.startPrice and s.salesValue < p.endPrice
GROUP BY p.[Price Band], t.[Country]
ORDER BY t.[Country], p.[Price Band]
Note: SQL Server does integer division of integers (so 3/2 = 1 not 1.5) and similarly for AVG(). It is more accurate to use a decimal point number. An easy way is to use AVG(items * 1.0).

How to find net rows from sales and cancel rows using sql

I have a table with columns mentioned below:
transaction_type transaction_number amount
Sale 2016040433 50
Cancel R2016040433 -50
Sale 2016040434 50
Sale 2016040435 50
Cancel R2016040435 -50
Sale 2016040436 50
I want to find net number of rows with only sales which does not include canceled rows.
(Using SQL Only).
If you just want to count the sales and subtract the cancels (as suggested by your sample data), you can use conditional aggregation:
select sum(case when transaction_type = 'Sale' then 1
when transaction_type = 'Cancel' then -1
else 0
end)
from t;
SELECT count(transaction_type) FROM TBL_NAME GROUP BY count(transaction_type) HAVING transaction_type = 'Sale'
Just use the count function, and use HAVING with GROUP BY to filter
The list of row
select transaction_number, amount
from table
where transaction_type ='Sale';
or sum
select sum(amount)
from table
where transaction_type ='Sale';
or count
select count(*)
from table
where transaction_type ='Sale';
Since you have the transaction number, which i assume is a unique identifier for each transaction, i would use it to count the net sale rows.
Assuming then than every Cancelled transaction number is 'R'+ Sales transact number, then the query i propose is the following:
WITH CancelledSales_CTE (transaction_type, transaction_number, amount)
AS
(
SELECT transaction_type, RIGHT(transaction_number, LEN(transaction_number) - 1), amount
FROM Sales
WHERE transaction_type IS 'Cancel'
)
SELECT count(transaction_number)
FROM Sales
where transaction_number not in
(select distinct transaction_number from CancelledSales_CTE )
CancelledSales_CTE contains the list of cancelled rows, with the transaction number of the relative sale.
The count coming from
SELECT count(transaction_number)
FROM Sales
where transaction_number not in
(select distinct transaction_number from CancelledSales_CTE )
will exclude the transaction numbers which have been canceled

SQL Query with count, sum and group by

Quick question if anyone has time to answer. The current query works great, but I need to also get a total count of the orders and the total shipping. I know the numbers are getting thrown off because of the joins.
I know that my count and sum will be:
count(DISTINCT orders.id) AS num_orders,
SUM(orders.shipping_cost_ex_tax) AS shipping
I think I need to use the count and sum in the original select and handle the rest in the join, but for the life of me I can't get this right.
Any help would be appreciated, even if it's "run a separate query". Thanks everyone.
Current query:
SELECT
IF(products.categories LIKE '68', 'Shirts', 'Books') AS group_key,
CONCAT(order_products.name) AS product_name,
brands.name AS author,
SUM(order_products.quantity) AS num_units,
CASE WHEN products.sku LIKE '%-WB' THEN 'Combo'
WHEN products.sku LIKE '%-BO' THEN 'Box'
ELSE ''
END AS item_type,
SUM(IF(order_products.discount IS NULL, order_products.price_ex_tax, (order_products.price_ex_tax - order_products.discount))) AS income
FROM orders
INNER JOIN order_products ON order_products.bc_order_id = orders.bc_id
INNER JOIN products ON order_products.bc_product_id = products.bc_id
INNER JOIN brands ON products.brand_id = brands.bc_id
WHERE (orders.created_at BETWEEN '2012-01-28 00:00:00' and '2012-02-21 23:00:00')
GROUP BY group_key,
case when products.brand_id = '68'
then products.name
else products.sku
end
Looking at the comment provided and not having your full schema in front of me. Would something like this work:
Table Report
(
id,
countOrders,
countSales,
countShipping,
countTax,
datePublished
)
Table SoldProducts
(
id,
price,
tax,
shippingPrice,
datePurchased
)
So what you would do in this instance is generate a report by querying from SoldProducts then you would persist the report that was generated.