Check the entries in a Table in postgresql - sql

In my postgresql table, there are four columns inc_id, expense_grp, money, year. Money is either 1 or -1 .
inc_id expense_grp money year
100 grocery 1 2017
200 food -1 2017
300 grocery -1 2018
400 food 1 2018
500 grocery -1 2017
600 food 1 2017
700 grocery -1 2018
800 food 1 2018
900 cloths 1 2018
1000 food -1 2018
Now, we need to find the sum of money for an expense_grp in a particular year.
As an example,
Ex 1 :-
money sum for expense_grp grocery in the year 2017 is (1 + (-1)) = 0
Ex 2 :-
money sum for expense_grp grocery in the year 2018 is ((-1) + (-1)) = -2
Now, Ex 1 is balanced because sum is 0 but Ex 2 is not balanced because sum is -2 . If we want to make Ex 2 balanced then we have to remove both the entries from the TABLE. To make it balanced either we have to make the sum 0 or remove the entries.
Not always it is required to remove all the entries. Suppose, if sum is like ((-1) + 1 + (-1)) = -1 , then we can remove the entry with -1 , so the target is to make the sum 0 . There are two entries with -1 , so we can remove by any order. Randomly we can pick one -1 and delete it.
I am looking for two solution queries like,
SELECT * FROM dataset (solution query will be added here) It will only show the entries of an expense_grp where sum is not balanced in a year.
It should return,
inc_id expense_grp money year
300 grocery -1 2018
400 food 1 2018
700 grocery -1 2018
800 food 1 2018
900 cloths 1 2018
1000 food -1 2018
SELECT * FROM dataset (solution query will be added here) It will show the balanced data that means after doing removal operation.
inc_id expense_grp money year
100 grocery 1 2017
200 food -1 2017
400 food 1 2018
500 grocery -1 2017
600 food 1 2017
900 cloths 1 2018
1000 food -1 2018
NOTE :- We have removed the entry 800 food 1 2018 to make the expense_grp food balanced in the year 2018 .
Also removed 300 grocery -1 2018 and 700 grocery -1 2018 from the TABLE because the Sum is -2.
One thing we have to consider here is that before removing a row, we have to see if it can be added into any other unbalanced expense_grp to make it balanced in a same year.
So basically what I want is that find all combinations of year and expense group where the sum of money != 0 Remove arbitrary records which cause the "imbalance" until the sum of money == 0
What is the recommended way to achieve this ?

Related

Need to find count of profit and loss and no data using select subquery

I have the following table
Years Months Credit Debit ProfitandLoss Symbol
2019 Jan 10000 2000 1000 P
2019 Aug 8000 1000 -10922 L
2019 May 5000 3000 2000 P
2020 Feb 10000 5000 800 P
2020 Apr 1000 6000 0 N
2020 Oct 2000 1000 2000 P
2021 Jan 6000 8000 -600 L
2021 Mar 2000 3000 1400 P
2021 Nov 2000 2000 0 N
Here I need to calculate total credit, total debit, total profit and loss and total count of profit, total count of loss, total count of nothing in one result table.
I have tried this but cannot get CountOfProfit, CountOfLoss and CountNothing according to years.
select Years,
SUM(credit) as [Total Credit],
SUM(debit) as totaldebit,
COUNT(Symbol) as totalcredit,
(select COUNT(Symbol) from Yearly where Symbol='P') as CountofProfit,
(select COUNT(Symbol) from Yearly where Symbol='L') as CountofLoss,
(select COUNT(Symbol) from Yearly where Symbol='N')as CountNothing
from Yearly
group by Years
My result table should be like
Years TotalCredit TotalDebit TotalProfitandLoss CountOfProfit CountofLoss CountofNothing
2019 23000 7000 -7022 2 1 0
2020 13000 12000 2800 2 0 1
2021 10000 13000 800 1 1 1
You need use conditional aggregation. This is achieved with a CASE expression:
SELECT Years,
SUM(Credit) AS TotalCredit,
SUM(Debit) AS TotalDebit,
SUM(ProfitandLoss) AS TotalProfitAndLoss,
COUNT(CASE Symbol WHEN 'P' THEN 1 END) AS Profits,
COUNT(CASE Symbol WHEN 'L' THEN 1 END) AS Losses,
COUNT(CASE Symbol WHEN 'N' THEN 1 END) AS Nothings
FROM (VALUES(2019,'Jan',10000,2000, 1000 ,'P'),
(2019,'Aug',8000 ,1000,-10922,'L'),
(2019,'May',5000 ,3000, 2000 ,'P'),
(2020,'Feb',10000,5000, 800 ,'P'),
(2020,'Apr',1000 ,6000, 0 ,'N'),
(2020,'Oct',2000 ,1000, 2000 ,'P'),
(2021,'Jan',6000 ,8000, -600 ,'L'),
(2021,'Mar',2000 ,3000, 1400 ,'P'),
(2021,'Nov',2000 ,2000, 0 ,'N'))V(Years,Months,Credit,Debit,ProfitandLoss,Symbol)
GROUP BY Years
ORDER BY Years;

Include "0" results in COUNT(*) aggregate

Good morning, I've searched in the forum one doubt that I have but the results that I've seen didn't give me a solution.
I have two tables.
CARS:
Id Model
1 Seat
2 Audi
3 Mercedes
4 Ford
BREAKDOWNS:
IdBd Description Date Price IdCar
1 Engine 01/01/2020 500 € 3
2 Battery 05/01/2020 0 € 1
3 Wheel's change 10/02/2020 110,25 € 4
4 Electronic system 15/03/2020 100 € 2
5 Brake failure 20/05/2020 0 € 4
6 Engine 25/05/2020 400 € 1
I wanna make a query that shows the number of breakdowns by month with 0€ of cost.
I have this query:
SELECT Year(breakdowns.[Date]) AS YEAR, StrConv(MonthName(Month(breakdowns.[Date])),3) AS MONTH, Count(*) AS [BREAKDOWNS]
FROM cars LEFT JOIN breakdowns ON (cars.Id = breakdowns.IdCar AND breakdowns.[Price]=0)
GROUP BY breakdowns.[Price], Year(breakdowns.[Date]), Month(breakdowns.[Date]), MonthName(Month(breakdowns.[Date]))
HAVING ((Year([breakdowns].[Date]))=[Insert a year:])
ORDER BY Year(breakdowns.[Date]), Month(breakdowns.[Date]);
And the result is (if I put year '2020'):
YEAR MONTH BREAKDOWNS
2020 January 1
2020 May 1
And I want:
YEAR MONTH BREAKDOWNS
2020 January 1
2020 February 0
2020 March 0
2020 May 1
Thanks!
The HAVING condition should be in WHERE (otherwise it changes the Outer to an Inner join). But as long as you don't use columns from cars there's no need to join it.
To get rows for months without a zero price you should switch to conditional aggregation (Access doesn't support Standard SQL CASE, but IIF?).
SELECT Year(breakdowns.[Date]) AS YEAR,
StrConv(MonthName(Month(breakdowns.[Date])),3) AS MONTH,
SUM(CASE WHEN breakdowns.[Price]=0 THEN 1 ELSE 0 END) AS [BREAKDOWNS]
FROM breakdowns
JOIN cars
ON (cars.Id = breakdowns.IdCar)
WHERE ((Year([breakdowns].[Date]))=[Insert a year:])
GROUP BY breakdowns.[Price], Year(breakdowns.[Date]), Month(breakdowns.[Date]), MonthName(Month(breakdowns.[Date]))
ORDER BY Year(breakdowns.[Date]), Month(breakdowns.[Date]

SSRS REPORT SQL

I have data as below
Year Period Country STATUS COST1 COST2 TOTAL COST
2019 1 Australia PERM 100 200 300
2019 2 NZ PERM 200 200 400
2019 3 ASIA TEMP 400 200 600
2019 4 NZ TEMP 500 200 700
I like to show in the SSRS report
I need period on COLUMN and STATUS in ROWS like below and total cost in data section
Period
1 2 3 4
+PERM TOTAL COST
+TEMP
And when end user toggle on + it will show more detail. But otherwise just like that.
Year Country COST1 COST2 TOTAL COST
PERM 2019 1 Australia 100 200 300
2019 2 NZ 200 200 400
TEMP 2019 3 ASIA 400 200 600
2019 4 NZ 500 200 700
thanks in advance
You seem to want conditional aggregation:
select status,
sum(case when period = 1 then total_cost else 0 end) as total_cost_1,
sum(case when period = 2 then total_cost else 0 end) as total_cost_2,
sum(case when period = 3 then total_cost else 0 end) as total_cost_3,
sum(case when period = 4 then total_cost else 0 end) as total_cost_4
from t
group by status;
With a Matrix in SSRS you can set the row groups to be based on the Period and Status without having to add an additional dataset.
Use Period for the Column Grouping so the field will expand to 4 columns based on the Period values.
Result:
This way you can have the detail below in the same table and hide it until the user toggles it.

sas is the column an even year?

I currently have data regarding income streams over four years, the income stream fills a 4x4 matrix as follows:
Year1 Year2 Year3 Year4
2017 10 15 20 25
2018 10 15 20 25
2019 10 15 20 25
2020 10 15 20 25
The income streams come from a debt instrument where the rows indicate when the debt was issued and the columns indicate the flow of income coming in per year.
I am trying to build another matrix to highlight whether or not the debt instrument was priced that year to create this matrix:
Year1 Year2 Year3 Year4
2017 1 0 0 0
2018 0 1 0 0
2019 0 0 1 0
2020 0 0 0 1
This is a very simple example and it goes on to work on how often the instrument is repriced etc. for simplicity, is there a way to create an if or where function that returns a 1 or 0 depending on whether the year is equal to or within a certain amount of time of the instrument being issued.
So far i'm thinking along the lines
%Repricing = 1
data want;
set have;
if Year[i] <= &Repricing;
then Year[i]=1;
run;
It's probably obvious that SAS isn't my language of choice, TIA.
Here's one way to do this, but I basically renamed the years to match the years of data - this is logic that was in your text but not in your data.
*sample data;
data have;
input YearD Year2017 Year2018 Year2019 Year2020;
cards;
2017 10 15 20 25
2018 10 15 20 25
2019 10 15 20 25
2020 10 15 20 25
;
run;
data want;
set have;
*arrays for years and flags;
array _year(2017:2020) year2017-year2020;
array _flag(2017:2020) flag2017-flag2020;
*loop over array;
do i=2017 to hbound(_year);
/*check if year matches year in variable name*/
if put(yearD, 4.) = compress(vname(_year(i)),, 'kd')
then _flag(i)=1;
else _flag(i)=0;
end;
drop i;
run;

how to calculate % in PPS 2010

i have these columns in the table and made this table as the FACT table and also using time intelligence filter in the PPS2010..
i have measures , sum (materials), sum (sales) and sum (material_%)
in the PPS dashboard design i have included this cube and all the measures.. and using an analytic chart..
i have developed separate graphs for each columns (material, sales, material_%)..
for the sales and materials there is no problem , when i use the time filter
in the material_% graph i used the time filter current quarter in months (showing three months ) shows the correct value..
when i use the current quarter filter (sum of all the 3 months)
its showing 146% (83 +33 +30) --> for actual values
and 150 % ( 50+50+50) --> for target values
actually it showed show me 46% for actual and 50% for target ,
it should be sum of material in all the 3 months / sum of sales in all the 3 months but its just calculating sum of material_% column of all the 3 months
time filter : year :: Halfyear ::quarter:: Month::Day
DataBase Table:
Month Year Material sales Material_% [ material / sales]
Jan_Act 2011 500 600 83
Jan_target 2011 400 800 50
Feb_Act 2011 300 900 33
Feb_target 2011 300 600 50
Mar_Act 2011 300 900 30
Mar_target 2011 300 600 50
......
Jan_Act 2012 0 0 0
Jan_target 2012 600 1000 60
.............
Dec_Act 2012 0 0 0
Dec_target 2012 600 800 75
MDX Query:
SELECT
HIERARCHIZE( { [Time_dim].[Year - Half Year - Quarter - Month - Date].DEFAULTMEMBER } )ON COLUMNS,
HIERARCHIZE( { [Ven Bi Actfctmaster].[Act Fct].&[ACTUAL], [Ven Bi Actfctmaster].[Act Fct].&[TARGET] } )ON ROWS
FROM [Vin Finance]
WHERE ( [Measures].[Materials - Ven Bifullrptmaster] )
Please help me to sort out this issue.
i solved this issue by changing the measure of '%' columns from sum to averageofchild in the property tab..