SSRS REPORT SQL - 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.

Related

Oracle - Getting the rows w/ condition of two columns having minimum values

I am a newbie to PLSQL. I would like to ask for your help.
I have a table below.
Item
Week
Qty
DMD_WK
DMD_QTY
ACC_DMD
WIP
H00978A510
26
300
26
0
0
1
H00978A510
26
300
27
0
0
2
H00978A510
26
300
28
300
300
3
H00978A510
26
300
29
100
400
3
H00978A510
26
300
30
100
500
4
first of all, I want to filter the records that has QTY < ACC_DMD. so the result will be below(I'm okay w/ this part)
Item
Week
Qty
DMD_WK
DMD_QTY
ACC_DMD
WIP
H00978A510
26
300
29
100
400
3
H00978A510
26
300
30
100
500
4
then, I need to get the row having the minimum DMD_WK and also having the minimum WIP grouped by item, week and qty after the filter being applied(Need help on this part)
so that the query will result in this:
Item
Week
Qty
DMD_WK
DMD_QTY
ACC_DMD
WIP
H00978A510
26
300
29
100
400
3
Hoping for your time and help, thanks in advance.
SELECT *
FROM YOURTABLE t
WHERE
DMD_WK = (SELECT MIN(tin.DMD_WK)
FROM YOURTABLE tin
WHERE tin.ITEM = t.ITEM AND tin.QTY < tin.ACC_DMD
GROUP BY tin.ITEM )
AND WIP = (SELECT MIN(tin.WIP)
FROM YOURTABLE tin
WHERE tin.ITEM = t.ITEM AND tin.QTY < tin.ACC_DMD
GROUP BY tin.ITEM )

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]

Check the entries in a Table in postgresql

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 ?

Filter SQL query results by aggregrate

I need a query that shows the JobIDs where the Worker has not been paid BUT where the Company has been paid. Below are the table columns and sample data:
tblInvoices columns:
-------------------
JobID
InvoiceID
WorkerPaidAmountTotal
CompanyPaidAmountTotal
Sample data
-----------
JobID | InvoiceID | WorkerPaidAmountTotal | CompanyPaidAmountTotal
1 30 100 150
1 31 0 100
2 32 0 75
3 33 25 50
3 34 10 30
4 35 0 0
I know how to get the SUM of the amounts paid to either a Worker or the Company. The results look like this:
JobID Worker Company
1 100 250
2 0 75
3 35 80
4 0 0
But what I need are the results of just the JobIDs where the Worker has got 0 and the company >0. The results I want should be this, but I can't figure out the query to do so:
JobID Worker Company
2 0 75
Use HAVING clause to filter the groups. Try this :
SELECT jobid,
Worker=Sum(WorkerPaidAmountTotal),
Company=Sum(CompanyPaidAmountTotal)
FROM tablename
GROUP BY jobid
HAVING Sum(WorkerPaidAmountTotal) = 0
AND Sum(CompanyPaidAmountTotal) > 0
select jobid, worker, company where WorkerPaidAmountTotal = 0 and CompanyPaidAmountTotal
Seems to plain to do it... may be i did'nt understand the question

Oracle SQL Query one row with monthly value only, but need to group it by month

I can't figure out the correct query on Oracle SQL
I have the following data:
Name Monthly_amount Start_date
Bob 100 April 2014
Mike 120 June 2014
Steve 80 Sept 2014
Bob 50 Dec 2014
And I would like to get the following result
Name |Jan-14| Feb-14| Mar-14| Apr-14 |May-14| Jun-14| Jul-14 |Aug-14|Sep-14|Oct-14| Nov-14| Dec-14
Bob 0 0 0 100 100 100 100 100 100 100 100 150
Mike 0 0 0 0 0 120 120 120 120 120 120 120
Steve 0 0 0 0 0 0 0 0 80 80 80 80
Something along the lines of this should work for you. If you need the column definitions to be dynamic, you would have to create it dynamically, but it's better to do that kind of things in your application.
SELECT Name,
SUM(CASE WHEN Start_date <= TO_DATE('01-JAN-2014','DD-MON-YYYY')
THEN Monthly_Amount ELSE 0 END) AS Jan14,
SUM(CASE WHEN Start_date <= TO_DATE('01-FEB-2014','DD-MON-YYYY')
THEN Monthly_Amount ELSE 0 END) AS Feb14,
(etc.)
FROM table1
GROUP BY Name;
(This assumes Name uniquely defines a person)