oracle grand total row and column wise? - sql

I want a query that will count the row wise and column wise total,i have found the way to calculate column wise count but not getting row wise count.
select nvl(to_char(R.LTHT_FLAG), 'total') as a,
SUM(CASE WHEN p.STATUS_CODE='0' OR p.STATUS_CODE='1' THEN 1 ELSE 0 END) K,
SUM(CASE WHEN p.STATUS_CODE='2' THEN 1 ELSE 0 END) W,
SUM(CASE WHEN p.STATUS_CODE='4' THEN 1 ELSE 0 END) C,
SUM(CASE WHEN p.STATUS_CODE='6' THEN 1 ELSE 0 END) R
from WORKASSIGNMENT P,RESOURCES R WHERE P.EMP_CODE=R.EMP_CODE
group by rollup (R.LTHT_FLAG);
the output of the following query is column wise count which is like.
A K W C R Total
DEVELOPMENT 1 18 397 0 ?
HT 43 21 673 0 ?
LT 83 14 7955 60 ?
SLD 306 9 4621 24 ?
----------------------------------------
total 433 62 13646 84 ?
but now i want row wise count for this output
Please help me to get the sum row-wise

Just add all the columns to get the total for each row.
For example,
SQL> WITH sample_data AS(
2 SELECT 'DEVELOPMENT' A, 1 k, 18 w, 397 c, 0 r FROM dual UNION ALL
3 SELECT 'HT' A, 43 k, 21 w, 673 c, 0 r FROM dual UNION ALL
4 SELECT 'LT' A, 83 k, 14 w, 7955 c, 60 r FROM dual UNION ALL
5 SELECT 'SLD' A, 306 k, 9 w, 4621 c, 24 r FROM dual
6 )
7 -- end of sample_data mimicking real table
8 SELECT t.*, k+w+c+r total FROM sample_data t;
A K W C R TOTAL
----------- ---------- ---------- ---------- ---------- ----------
DEVELOPMENT 1 18 397 0 416
HT 43 21 673 0 737
LT 83 14 7955 60 8112
SLD 306 9 4621 24 4960
SQL>
Above, instead of sample_data, put your current SQL as a sub-query in the FROM clause.

Related

Is there a way to query a table referencing the result column for prior periods?

The Problem
I want to perform a query using the aggregate results of all time periods prior in the current time period calculations, for each ID.
The solution I have come up with would be to do each time period separately, but this is problematic as the the number of time periods change.
Is there a way to query this using a general approach that does not require hardcoding the result set for each time period?
The Math
For each ID in the data the calculations would be as follows
In time period 0 the aggregate should be zero and the equation would be:
For time period 1 it should be:
And to show the goal, I'll jump to time period 3:
For ID1 and time period 3 the result would be:
As seen in the WANT column in the data below
The Data
The data I have is ID, T, B, P and A. WANT is the expected result, and should match R in the equations
ID
T
B
P
A
WANT
ID1
0
25
0
75
0,0000
ID1
1
25
5
70
1,7857
ID1
2
20
8
67
2,6013
ID1
3
15
32
43
14,4275
ID2
0
25
0
75
0,0000
ID2
1
20
5
70
1,4286
ID2
2
17
8
67
2,2004
ID2
3
10
32
43
10,1425
ID3
0
25
0
75
0,0000
ID3
1
25
5
70
1,7857
ID3
2
25
8
67
3,1983
ID3
3
5
32
43
7,4300
Example data
Now with solution provided by gsalem:
sqlfiddle
Try this in you dbfiddle:
with get_rates (id, t, b, p, a, prt, w) as
(select id, t, b, p,a, 0 prt, (0+b)*p/A w
from data
where T=0
union all
select a.id, a.t, b.b,b.p, b.a, b.prt+w,(b.prt+b.w+a.b)*a.p/a.a
from data a join get_rates b on (a.id=b.id and a.t=b.t+1))
select id,t,b,p,a,w
from get_rates
order by id,t

Merge two row into two column with third column same as it is

I have SQL output like this :
LINE SIZE TOT_COUNT
A 20 113
A 40 3
B 20 4
B 40 2
C 20 142
C 40 452
But I want like this:
LINE 20 40
A 113 3
B 4 2
C 142 452
Note: This is already a output, not any column of any table.
select
line,
sum(case size when 20 then tot_count end) as "20", -- use min is the same.
sum(case size when 40 then tot_count end) as "40"
from
your_table
group by
line
If the first output is from another query, you can replace your_table with your query as an sub query.

How to create a flag of exclusion for duplicate rows in Oracle

Given below is the snapshot of my data
NameAgeIncome Group
Asd 20 A
Asd 20 A
b 19 E
c 21 B
c 21 B
c 21 B
df 21 C
rd 24 D
I want ot include a flag variable where it says 1 to one of the duplicate row and 0 to another. And also 0 to rest of the rows which are not duplicate. Given below is the snapshot of final desired output
NameAgeIncome Group Flag
Asd 20 A 1
Asd 20 A 0
b 19 E 0
c 21 B 1
c 21 B 1
c 21 B 0
df 21 C 0
rd 24 D 0
Can anyone help me how to create this Flag variable in Oracle database
You can do this using analytic functions and case:
select t.*,
(case when row_number() over (partition by name, age, income order by name) = 1
then 0 else 1
end) as GroupFlag
from table t;

Combining Rows and Taking Averages

I have a table that looks like
#Sector max1 avg1 max2 avg2 numb
C 133 14 45 3 27
N 174 9 77 3 18
M 63 3 28 1 16
I would like to join rows N and M together call it X and take the max value of max1 and max2 while taking the avg of avg1, avg2, and numb in their respective columns to return
#Sector max1 avg1 max2 avg2 numb
C 133 14 45 3 27
X 174 6 77 2 17
Try this way:
select sector, max1,avg1,max2,avg2,numb
from tab
where sector not in ('M','N')
union all
select 'X' as sector, max(max1),avg(avg1),max(max2),avg(avg2),avg(numb)
from tab
where sector in ('M','N')
something like:
select
case when sector in ('N','M') then 'X' else sector end sect,
max(max1) max1,
avg(avg1) avg1,
max(max2) max2,
avg(avg2) avg2,
avg(numb) numb
from tabname
group by
case when sector in ('N','M') then 'X' else sector end

sum of differencies of rows

I have example values in column like this:
values
-------
89
65
56
78
74
73
45
23
5
654
643
543
345
255
233
109
43
23
2
The values are rising up and then fall down to 0 and rising up again.
I need to count differencies between rows in new column and the sum of these differencies too (cumulative sum) for all values. The values 56 and 5 are new differencies from zero
The sum is 819.
Example from bottom> (23-2)+(43-23)+(109-43)+..+(654-643)+(5)+(23-5)+..
Okay, here is my try. However, you need to add an Identity field (which I called "AddSequence") that starts with 1 for the first value ("2") and increments by one for every other value.
SELECT SUM(C.Diff) FROM
(
SELECT CASE WHEN (A.[Value] - (SELECT [Value] FROM [TestValue] AS B WHERE B.[AddSequence]= A.[AddSequence]-1)) > 0
THEN (A.[Value] - (SELECT [Value] FROM [TestValue] AS D WHERE D.[AddSequence]= A.[AddSequence]-1))
ELSE 0
END AS Diff
FROM [TestValue] AS A
) AS C
The first solution I had neglected that fact that we had to start over whenever the difference was negative.
I think you are looking for something like:
SELECT SUM(a - b)) as sum_of_differences
FROM ...
I think you want this for the differences, I've tested it in sqlite
SELECT CASE WHEN (v.value - val) < 0 THEN 0 ELSE (v.value - val) END AS differences
FROM v,
(SELECT rowid, value AS val FROM v WHERE rowid > 1) as next_val
WHERE v.rowid = next_val.rowid - 1
as for the sums
SELECT SUM(differences) FROM
(
SELECT CASE WHEN (v.value - val) < 0 THEN 0 ELSE (v.value - val) END AS differences
FROM v,
(SELECT rowid, value AS val FROM v WHERE rowid > 1) AS next_val
WHERE v.rowid = next_val.rowid - 1
)
EDITED - BASED OFF OF YOUR QUESTION EDIT (T-SQL)
I don't know how you can do this without adding an Id.
If you ad an Id - this gives the exact output you had posted before your edit. There's probably a better way, but this is quick and dirty - for a one time shot. Using a SELF JOIN. Differences was the name of your new column originally.
UPDATE A
SET differences = CASE WHEN A.[values] > B.[Values] THEN A.[values] - B.[Values]
ELSE A.[values] END
FROM SO_TTABLE A
JOIN SO_TTABLE B ON A.ID = (B.ID - 1)
OUTPUT
Select [Values], differences FROM SO_TTABLE
[values] differences
------------------------
89 24
65 9
56 56
78 4
74 1
73 28
45 22
23 18
5 5
654 11
643 100
543 198
345 90
255 22
233 124
109 66
43 20
23 21
2 0