SQL views, grouping by most sold items and customers who purchased most - sql

This is my table:
Using this query, I am getting most sold items:
SELECT [Purchased Item], SUM([Overall Quantity purchased] )
FROM ReportDraft
GROUP BY [Purchased Item]
ORDER BY SUM([Overall Quantity purchased] )
This returns items and total quantity purchased by customer.
Can I somehow create a table like
ItemName | Total quantity purchased | Customer who purchased most | Customer quantity bought
Pie--------|---------11------------|---------------ALEX----------|--------3------------|
Thank you

I would use window functions and conditional aggregation:
SELECT [Purchased Item], sum(total) as total,
MAX(CASE WHEN seqnum = 1 THEN Customer END) as customer,
MAX(Total) as max_quantity
FROM (SELECT [Purchased Item], Customer, SUM([Overall Quantity purchased] ) as total,
ROW_NUMBER() OVER (PARTITION BY Customer ORDER BY SUM([Overall Quantity purchased]) DESC) as seqnum
FROM ReportDraft
GROUP BY [Purchased Item], Customer
) rd
GROUP BY [Purchased Item]
ORDER BY SUM([Overall Quantity purchased] );

Related

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.

Decile analysis - customer and revenue and vice versa

I am trying to produce an analysis which shows 2 things.
Deciles (or percentiles) of customers and their revenue so I can see what 10% of customer count produce the the most revenue.
Deciles of Revenue : how many customers produce 10% of revenue.
select yeardate, decile, sum(revenue) as revenue, count(distinct(customername)) as cust_count
from
(
select yeardate,
customername,
ntile(10) over (order by sum(revenue) ) as decile,
sum(revenue) as revenue
from
(select
year(DateStamp) as yeardate ,
customername,
sum(Sell) as revenue
from MarginListView
where reporttype = 'Invoice' and sell >0 and year(datestamp) = 2018
group by year(DateStamp), customername) d
group by yeardate, CustomerName) c
group by yeardate, decile
order by 1,2
I can get the customer count deciles but not the revenue deciles....
using MS SQL server - Any help appreciated.
To get the number of customers that produce 10% of revenue, start with the cumulative revenue:
select customername, sum(sell) as revenue,
sum(sum(sell)) over (order by sum(sell) desc) as running_revenue
from MarginListView
where reporttype = 'Invoice' and sell > 0 and
year(datestamp) = 2018
group by customername;
To get the number that account for 10%:
select count(*)
from (select customername, sum(sell) as revenue,
sum(sum(sell)) over (order by sum(sell) desc) as running_revenue,
sum(sum(sell)) over () as total_revenue
from MarginListView
where reporttype = 'Invoice' and sell > 0 and
year(datestamp) = 2018
group by customername
) c
where running_revenue - revenue >= 0.1 * total_revenue;
Gordon - thanks for your help.... it really did get me towards where I needed to be.
I ended with this...
select
yeardate, customername,
sell,
cast((round(sum(sum(revenue_sub_tot)) over (order by sum(revenue_sub_tot) asc),2,2)) as decimal (2,2)) as revenue_percentiles,
cast((round(sum(sum(revenue_sub_tot)) over (order by sum(revenue_sub_tot) asc),1,1)) as decimal (2,2)) as revenue_deciles
from (select year(datestamp) as yeardate,
customername,
sum(sell) as sell,
sum(sell)/sum(sum(sell)) over () as revenue_sub_tot
from MarginListView
where reporttype = 'Invoice' and sell > 0
group by year(datestamp), customername
) c
group by yeardate, customername, sell
order by 1,3

SQL views, Groupping + inner join the same table

This is my table:
Using this query, I am getting most sold items:
SELECT [Purchased Item], SUM([Overall Quantity purchased] )
FROM ReportDraft
GROUP BY [Purchased Item]
ORDER BY SUM([Overall Quantity purchased] )
This returns items and total quantity purchased by customer.
how I can create a table like this
ItemName | Total quantity purchased | Customer who purchased most | Customer quantity bought
Pie--------|---------6------------|---------------Tonya----------|--------4------------|
Big Burger-|---------3------------|---------------Tonya----------|--------3------------| and etc
Thank you
Why do you post a new question instead of nodifying/extending the previous one?
WITH cte AS
(
SELECT [Purchased Item],
-- quantity per item
SUM(SUM([Overall Quantity purchased]))
OVER (PARTITION BY [Purchased Item]) AS "Total quantity purchased",
[Customer name],
-- quantity per item/customer
SUM([Overall Quantity purchased]) AS customer_qantity,
-- rank the customer quantity per item
ROW_NUMBER()
OVER (PARTITION BY [Purchased Item]
ORDER BY SUM([Overall Quantity purchased]) DESC) AS rn
FROM ReportDraft
GROUP BY [Purchased Item], [Customer name]
)
SELECT *
FROM cte
WHERE rn = 1
ORDER BY "Total quantity purchased" DESC

Using Subquery And Ordering The Value By Date

I'm Trying to Get the date , Discount , Total , Net Total ... ordered by date , the discount is showing the real amount but when I select multiple dates the total will be summed in those dates I've selected and it will be ordered by date
DECLARE #pR FLOAT = (SELECT SUM(CAST(Price AS FLOAT)) AS Price
FROM Orders WHERE isPaid = 1
AND PaidDate BETWEEN '8/17/2015' AND '8/18/2015' ) ;
SELECT Orders.PaidDate
, #pR AS Total
,sum(theorderids.Discount) As Discount
,(#pR - sum(theorderids.Discount)) AS [Net Total]
From
(SELECT OrderId, PaidDate
FROM Orders
WHERE Orders.PaidDate BETWEEN '8/17/2015' AND'8/18/2015'
GROUP BY Orders.OrderId, Orders.PaidDate) AS Orders
INNER JOIN theorderids ON Orders.OrderId = theorderids.ID
GROUP BY Orders.PaidDate ;
Example Data :
Row 1
"PaidDate": "17-08-2015",
"Total": 7388.0,
"Discount": 38.0,
"NetTotal": 7363.0
Row 2
"PaidDate": "18-08-2015",
"Total": 7388.0,
"Discount": 2.0,
"NetTotal": 7363.0
This will work.
SELECT TheOrderids.PaidDate, MAX(Price) AS Total
,sum(theorderids.Discount) As Discount
,(MAX(Price) - sum(theorderids.Discount)) AS [Net Total]
From
(SELECT PaidDate ,SUM(Price ) AS Price
FROM Orders
WHERE Orders.PaidDate BETWEEN '8/17/2015' AND'8/19/2015'
GROUP BY Orders.PaidDate
) AS Orders
INNER JOIN theorderids ON Orders.PaidDate = theorderids.PaidDate
GROUP BY theorderids.PaidDate
ORDER BY theorderids.PaidDate ;
Try this way
SELECT Orders.PaidDate
, #pR AS Total
,sum(theorderids.Discount) As Discount
,(#pR - sum(theorderids.Discount)) AS [Net Total]
From
(SELECT ROW_NUMBER() OVER(ORDER BY Orders.PaidDate ) AS Row, OrderId, PaidDate
FROM Orders
WHERE Orders.PaidDate BETWEEN '8/17/2015' AND'8/18/2015'
GROUP BY Orders.OrderId, Orders.PaidDate) AS Orders
INNER JOIN theorderids ON Orders.OrderId = theorderids.ID
GROUP BY Orders.PaidDate ;

SQL - Remove duplicates to show the latest date record

I have a view which ultimately I want to return 1 row per customer.
Currently its a Select as follows;
SELECT
Customerid,
MAX(purchasedate) AS purchasedate,
paymenttype,
delivery,
amount,
discountrate
FROM
Customer
GROUP BY
Customerid,
paymenttype,
delivery,
amount,
discountrate
I was hoping the MAX(purchasedate) would work but when I do my groupings it breaks as sometimes there could be a discountrate, sometimes its NULL, paymenttype can differ for each customer also, is there anyway just to show the last purchase a customer makes?
since SQL Server 2008 r2 supports windows function,
SELECT Customerid,
purchasedate,
paymenttype,
delivery,
amount,
discountrate
FROM
(
SELECT Customerid,
purchasedate,
paymenttype,
delivery,
amount,
discountrate,
ROW_NUMBER() OVER (Partition By CustomerID
ORDER BY purchasedate DESC) rn
FROM Customer
) derivedTable
WHERE derivedTable.rn = 1
or by using Common Table Expression
WITH derivedTable
AS
(
SELECT Customerid,
purchasedate,
paymenttype,
delivery,
amount,
discountrate,
ROW_NUMBER() OVER (Partition By CustomerID
ORDER BY purchasedate DESC) rn
FROM Customer
)
SELECT Customerid,
purchasedate,
paymenttype,
delivery,
amount,
discountrate
FROM derivedTable
WHERE derivedTable.rn = 1
or by using join with subquery which works in other DBMS
SELECT a.*
FROM Customer a
INNER JOIN
(
SELECT CustomerID, MAX(purchasedate) maxDate
FROM Customer
GROUP BY CustomerID
) b ON a.CustomerID = b.CustomerID AND
a.purchasedate = b.maxDate