How to sort by Total Sum calculated field in a Tablix - sql

I have a Report in Microsoft Visual Studio 2010 that has a tablix. I have a list of Customers Sales grouped by Month. I would like to add a grand total of all the Months for each customer. I would then like to sort by descending amount of the grand total. I have added the grand total, but I can't figure out how to sort on it. Any suggestions?
Here is the initial dataset query:
SELECT
Customer, CustomerName, FiscalMonthNum, FiscalYear, SalesDlr
FROM
CustomerSalesDollars
WHERE
FiscalYear IN ('2013')
ORDER BY
SalesDlr DESC

with CSD as (
select Customer, CustomerName, FiscalMonthNum, FiscalYear, SalesDlr
from CustomerSalesDollars
WHERE FiscalYear in ('2013')
), YearlyTotals as (
select FiscalYear, Customer, CustomerName, SUM(SalesDlr) as YearlyTotal
from CSD
group by FiscalYear, Customer, CustomerName
)
select * from YearlyTotals
order by YearlyTotal desc
If you still want all the monthly breakdowns:
with CSD as (
select Customer, CustomerName, FiscalMonthNum, FiscalYear, SalesDlr
from CustomerSalesDollars
WHERE FiscalYear in ('2013')
), YearlyTotals as (
select FiscalYear, Customer, CustomerName, SUM(SalesDlr) as YearlyTotal
from CSD
group by FiscalYear, Customer, CustomerName
)
select CSD.*, YT.YearlyTotal from YearlyTotals YT
join CSD on CSD.FiscalYear = YT.FiscalYear
and CSD.Customer = YT.Customer
and CSD.CustomerName = YT.CustomerName
order by YearlyTotal desc, CSD.SalesDlr desc

Related

How to add a new column that summarize rows

I have two issues :
I used 'Rollup' function to add Totals per Month and Year and I would like to change 'NULL' into grand_total as in the attached screenshot
I dont know how to add a new column that will summarize values starting from the second row
Please see attached screenshot of the results I need to receive and an example for a code from my side with a screenshot of the source output : [1]: https://i.stack.imgur.com/6B70o.png
[1]: https://i.stack.imgur.com/E2x8K.png
Select Year(Modifieddate) AS Year,
MONTH(modifieddate) as Month,
Sum(linetotal) as Sum_price
from Sales.SalesOrderDetail
Group by rollup( Year(Modifieddate),MONTH(modifieddate))
Thanks in advance,
I think this will work:
Select Year(Modifieddate) AS Year,
coalesce(convert(varchar(255), month(modifieddate)), 'Grand Total') as Month,
Sum(linetotal) as Sum_price,
sum(sum(linetotal)) over (partition by Year(Modifieddate)
order by coalesce(month(modifieddate), 100)
) as ytd_sum_price
from Sales.SalesOrderDetail
Group by rollup( Year(Modifieddate), month(modifieddate))
The coalesce() in the order by is to put the summary row last for the cumulative sum.
Like this:
Select Year(Modifieddate) AS Year, MONTH(modifieddate) as Month, Sum(linetotal) as Sum_price
from Sales.SalesOrderDetail
Group by rollup( Year(Modifieddate),MONTH(modifieddate))
UNION
Select Year(Modifieddate) AS Year, 'grand_total' as Month, Sum(linetotal) as Sum_price
from Sales.SalesOrderDetail
Group by Year(Modifieddate)
-- SQL SERVER
SELECT t.OrderYear
, CASE WHEN t.OrderMonth IS NULL THEN 'Grand Total' ELSE CAST(t.OrderMonth AS VARCHAR(20)) END b
, t.MonthlySales
, MAX(t.cum_total) cum_total
FROM (SELECT
YEAR(OrderDate) AS OrderYear,
MONTH(OrderDate) AS OrderMonth,
SUM(SubTotal) AS MonthlySales,
SUM(SUM(SubTotal)) OVER (ORDER BY YEAR(OrderDate), MONTH(OrderDate) ROWS UNBOUNDED PRECEDING) cum_total
FROM Sales.SalesOrderHeader
GROUP BY GROUPING SETS ((YEAR(OrderDate), MONTH(OrderDate)))) t
GROUP BY GROUPING SETS ((t.OrderYear
, t.OrderMonth
, t.MonthlySales), t.OrderYear);
Please check this url https://dbfiddle.uk/?rdbms=sqlserver_2019&sample=adventureworks&fiddle=e6cd2ba8114bd1d86b8c61b1453cafcf
To build one #GordonLinoff's answer, you are really supposed to use the GROUPING() function to check whether you are dealing with the grouping column. This behaves better in the face of nullable columns.
Select case when grouping(Year(Modifieddate)) = 0
then Year(Modifieddate)
else 'Grand Total' end AS Year,
case when grouping(month(modifieddate)) = 0
then convert(varchar(255), month(modifieddate))
else 'Grand Total' end as Month,
Sum(linetotal) as Sum_price,
sum(sum(linetotal)) over (
partition by
grouping(Year(Modifieddate)),
grouping(month(modifieddate)),
Year(Modifieddate)
order by month(modifieddate)
) as ytd_sum_price
from Sales.SalesOrderDetail
Group by rollup( Year(Modifieddate), month(modifieddate));

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

Grouping by several variables in SAS

I want to sum up sales across agents, orders and the date. The following code runs, however, I just receive a duplicate of the total column instead of the sum. Any advice?
CODE:
(Select DISTINCT DATE, CUSTOMER, ORDERNR,
AREA, AGENT, Total, SUM(Total) AS TOTALSUM From data01 WHERE REPORT_DT between '2018-02-24' and '2018-02-25' GROUP BY DATE, CUSTOMER, ORDERNR,
AREA, AGENT, Total, ORDER BY AGENT)
Just a suggestion for clean your code that contain some error
You don't need distinct whe use GROUP BY and you have a wrong comma after the word Total in group by
(Select
DATE
, CUSTOMER
, ORDERNR
, AREA
, AGENT
, Total
, SUM(Total) AS TOTALSUM
From data01
WHERE REPORT_DT between '2018-02-24' and '2018-02-25'
GROUP BY DATE
, CUSTOMER
, ORDERNR
, AREA
, AGENT
, Total
ORDER BY AGENT)
Remove Total from the GROUP BY:
Select DATE, CUSTOMER, ORDERNR, AREA, AGENT, SUM(Total) AS TOTALSUM
From data01
where REPORT_DT between '2018-02-24' and '2018-02-25'
group by DATE, CUSTOMER, ORDERNR, AREA, AGENT;

Microsoft SQL Server - Percentages of orders

I'm training on Northwind sample database and got task to do:
"Create query that returns: CompanyName, OrderID, SaleAmount (Value of that Order), Percentage value of that order, Total Value of Customers Orders.
I did it, everything works fine but now i want to add something else:
I want to add field that will show percentage share of individual order comaring it to total value of all orders - Sum(SaleAmount)
I did something like this:
SELECT
CompanyName,
OrderID,
SaleAmount,
CAST(100 * SaleAmount / SUM(SaleAmount) OVER (PARTITION BY CompanyName) AS decimal(5, 2)) AS 'Percent',
SUM(SaleAmount) OVER (PARTITION BY CompanyName) AS Total,
(SELECT
SUM(SaleAmount) AS Całość_Zamówienia
FROM dbo.[Sales Totals by Amount])
AS Suma_całkowita,
CAST(100 * SaleAmount / SUM(SaleAmount) OVER (PARTITION BY CompanyName) AS decimal(11, 2)) AS 'TEST'
FROM dbo.[Sales Totals by Amount]
GROUP BY CompanyName,
OrderID,
SaleAmount
But it shows stupid things, can you help me please? : )
Try this:
SELECT CompanyName, OrderID, SaleAmount,
CAST(100 * SaleAmount / SUM(SaleAmount) OVER(PARTITION BY CompanyName) as decimal(5,2)) as 'Percent',
SUM(SaleAmount) OVER(PARTITION BY CompanyName) as Total,
(SELECT Sum(SaleAmount) as Całość_Zamówienia FROM dbo.[Sales Totals by Amount]) as Suma_całkowita
,CAST(100 * SUM(SaleAmount) OVER(PARTITION BY CompanyName)/ (select sum(SaleAmount) from dbo.[Sales Totals by Amount]) as decimal(11,2)) as 'TEST'
FROM dbo.[Sales Totals by Amount]
GROUP BY CompanyName, OrderID, SaleAmount

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