Calculating sum of a column in a dataset - jasper-reports

I have the following query for a dataset:
select item, sum(salesAmount) as TotalSales from sales
group by item
order by TotalSales desc;
and I have set REPORT_COUNT<=5 for limiting the data to 5 records only.
Now I want to display top 5 items through a list component and their Sales Amount in percentage to that of the TotalSales amount of the top 5 items.
I have tried to create a variable in the dataset as
sales_sum
class: BigDecimal
Calculation : Sum
Reset Type : Report
Increment Type : None
Variable Expression : $F{TotalSales}
But the sales_sum increments with each row in the list. thus gives inaccurate value
for the percentage. What should I do?

It is because of the evaluation time of sales_sum variable , as I understand this variable is calculating sum row wise i.e for first row sum will be same as TotalSales value then for second row sum will be first value of and second value of TotalSales and so on, so you will be getting 1st % always 100.
To change this Evaluation Time property select the field where you are using sales_sum variable like for sales percentage and go to the property of that field and change the Evaluation Time property to :-
Evaluation Time Auto
Second solution:-
SELECT a.item,a.TotalSales, (a.TotalSales/a.Total) * 100 as Total_Perc
FROM
(select item,
sum(salesAmount) as TotalSales,
(select sum(salesAmount) as TotalSales from sales
order by TotalSales desc
limit 5) Total
from sales
group by item
order by TotalSales desc
limit 5) a;

Related

Conditionally select most common value in an array in PostgreSQL

I have a table (only one row) in my PostgreSQL 9.5 db with two columns i.e., count (bigint) and array (text).
count array
6 "112,19.3,142,142,19.3,172,172,20.3,202,202,20.3,232,232,19.3,262,262,19.3,292"
The array represents six (thus count = 6) set of values i.e., Lower_limit, Value and Upper_limit. Now, I need to conditionally modify my array i.e., when upper limit and lower limits are coinciding then select the first upper limit and last lower limit and return the most common value (which is 19.3) among the limits. My desired output would be like:
count array
1 112, 19.3, 292
Could anyone help me to have some pointers towards my desired output?
I must admin - I dont understand how you get count =1, but below is an example of how you can build array with firsrt, last and most common values. Mind if there would be several mos common values it would unpredictably pick on of em
t=#
with a(r) as (values(array[112,19.3,142,142,19.3,172,172,20.3,202,202,20.3,232,232,19.3,262,262,19.3,292]))
, p as (select * from a,unnest(a.r) with ordinality)
, t as (
select count(1) over (partition by unnest)
, unnest u
, r[1] a
, r[array_length(r,1)] e
from p
order by unnest
limit 1
)
select array[a,u,e]
from t
;
array
----------------
{112,19.3,292}
(1 row)

Sum up the count

I have a table like this:
Count Product
100 apple
50 apple
20 orange
How can I select to get the sum of the count per product like this?
Count Product
150 apple
20 orange
Try Query using SUM(),
select SUM(count) as count,Product from #YourTable
group by Product
SUM() function returns the total sum of a numeric column
You should use Aggregate Functions :
select SUM(count) as Count, Product from Product
group by Product

How to reference output rows with window functions?

Suppose I have a table with quantity column.
CREATE TABLE transfers (
user_id integer,
quantity integer,
created timestamp default now()
);
I'd like to iteratively go thru a partition using window functions, but access the output rows, not the input table rows.
To access the input table rows I could do something like this:
SELECT LAG(quantity, 1, 0)
OVER (PARTITION BY user_id ORDER BY created)
FROM transfers;
I need to access the previous output row to calculate the next output row. How can i access the lag row in the output? Something like:
CREATE VIEW balance AS
SELECT LAG(balance.total, 1, 0) + quantity AS total
OVER (PARTITION BY user_id ORDER BY created)
FROM transfers;
Edit
This is a minimal example to support the question of how to access the previous output row within a window partition. I don't actually want a sum.
It seems you attempt to calculate a running sum. Luckily that's just what Sum() window function does:
WITH transfers AS(
SELECT i, random()-0.3 AS quantity FROM generate_series(1,100) as i
)
SELECT i, quantity, sum(quantity) OVER (ORDER BY i) from transfers;
I guess, looking at the question, that the only you need is to calculate a cumulative sum.
To calculate a cumulative summ use this query:
SELECT *,
SUM( CASE WHEN quantity IS NULL THEN 0 ELSE quantity END)
OVER ( PARTITION BY user_id ORDER BY created
ROWS BETWEEN unbounded preceding AND current row
) As cumulative_sum
FROM transfers
ORDER BY user_id, created
;
But if you want more complex calculations, especially containing some conditions (decisions) that depend on a result from prevoius row, then you need a recursive approach.

How to add a sum of a column where the id is matching to another column in SQL

My table has columns called id, totalsales, and p_sales. p_sales is an empty column that I added and I want to fill in this column with the sum of totalsales where the id is matching.
For example, if the first row has an id of 2, I want the p_sales to be filled with the sum of all totalsales with the id of 2. In the next row, if the id is 6 I want the p_sales to be filled with the sum of all totalsales with an id of 6 and so on so forth.
How do I achieve this using SQL?
Try this, only change table1 and table2 with the name of the tables you need
update dodge t set p_sales = (select sum(t2.totalsales)
from dodge t2 where t2.p_id = t.p_id) ;

Show data from quarterly records in a single row

Each quarter's sales data is contained in a row in the data source.
Account 1's 4 quarters of sales data would be in 4 separate records, each containing the account name, quarter number, and count of items purchased.
The report should show, in each detail row: account name, q1 count, q2 count, q3 count, q4 count, total year count.
I'm new to Crystal, but it seems like this should be easy; how would I do this?
I'd probably create the result list using some slightly complex sql and they just display it on the Crystal report...but if you're wanting to accomplish this entirely inside Crystal, take a look at http://aspalliance.com/1041_Creating_a_Crosstab_Report_in_Visual_Studio_2005_Using_Crystal_Reports.all.
Here's a stab at the SQL that would be required...
select
accountName,
(select sum(itemCount) from myTable where quarterName = 'q1') as q1Count,
(select sum(itemCount) from myTable where quarterName = 'q2') as q2Count,
(select sum(itemCount) from myTable where quarterName = 'q3') as q3Count,
(select sum(itemCount) from myTable where quarterName = 'q4') as q4Count,
(select sum(itemCount) from myTable) as yearCount
from myTable
group by accountName ;
If your data source has the sales date in it (and I assume it would), you can create a formula called #SalesQuarter:
if month({TableName.SalesQuarter}) in [1,2,3] then '1' else
if month({TableName.SalesQuarter}) in [4,5,6] then '2' else
if month({TableName.SalesQuarter}) in [7,8,9] then '3'
else '4'
You can then add a cross-tab to your report, and use the new #SalesQuarter field as the column header of your cross-tab.
This assumes your sales are all within the same year.
Add a group on {account}
In the group footer add a Running total for each quarter.
For each quarter, create a running total with following settings:
Running Total Name: create a unique name for each formula, for example Q1,Q2,Q3,Q4
Field to summarize: {items purchased}
Type of summary: sum
Evaluate: Use a formula - {quarter number}= --should be 1,2,3, or 4, depending on which quarter you are summing
Reset: On Change of Group {account}