Dynamic Columns With Calculated Values - dynamic

1) StructureTable:
StrId StrName Figure Base On
1 Basic 40 Percent Total
2 D.A. 3495 Amount Total
3 O.A. 0 Remaining Total
2) SalaryTable
StaffId StaffName Salary
1 Ram 25000
2 Shyam 40000
3 Hari 30000
4 Ganesh 15000
3) IncrementTable
StaffId IncAmt
1 5000
2 3000
3 2000
4 4000
Desired Columns Resulted Output by Pivot or others:
StaffId StaffName Basic_Salary D.A_Salary O.A_Salary Total_Salary Basic_Inc D.A_Inc O.A_Inc Total_Inc Basic_Total D.A_Total O.A_Total Total_Total
1 Ram 10000 3495 18495 25000 2000 0 3000 5000 12000 3495 21495 30000
2 Shyam 16000 3495 27495 40000 1200 0 1800 3000 17200 3495 29295 43000
3 Hari 12000 3495 21495 30000 800 0 1200 2000 12800 3495 22695 32000
4 Ganesh 6000 3495 12495 15000 1600 0 2400 4000 7600 3495 14895 19000
Total 44000 13980 79980 110000 5600 0 8400 14000 49600 13980 88380 124000

Related

plsql sum another table values to joined tables

I have 3 tables.First table is student.Second is student_detail and last one special_codes.
student table
studentname | invoiceno |tax |invoiceamount
Paul 10 500 1950
Georghe 20 1000 6850
Mary 30 1500 1900
Messy 40 2000 7050
studentdetail
invoiceno | code | product | amount
10 101 pencil 100
10 102 rubber 350
10 103 bag 1500
20 108 wheel 5000
20 109 tv 1500
20 110 ps 300
20 111 mouse 50
30 103 bag 1500
30 105 keyboard 400
40 111 mouse 50
40 112 car 7000
I can join these two table like this and get result table
select s.studentname,s.tax,s.invoiceamount,st.product,sum(st.amount) from student s, studentdetail st
where s.invoiceno = st.invoiceno
group by
s.studentname,
s.tax,
s.invoiceamount,
st.product
result table
studentname tax invoiceamount product amount
Paul 500 1950 bag 1500
Paul 500 1950 pencil 100
Paul 500 1950 rubber 350
Messy 2000 7050 car 7000
Messy 2000 7050 mouse 50
Mary 1500 1900 bag 1500
Mary 1500 1900 keyboard 400
Georghe 1000 6850 mouse 50
Georghe 1000 6850 ps 300
Georghe 1000 6850 tv 1500
Georghe 1000 6850 wheel 5000
Last table is special codes.It contains only one column which is called code
specialcodes table
code
101
102
113
104
105
110
111
What i want to do is to look up studentdetail table and to find codes that are same in specialcodes.Then to sum amount values and write sum to result table as another column.Result table
should be like that
result table(final)
studentname tax invoiceamount product amount taxexclude
Paul 500 1950 bag 1500 450
Paul 500 1950 pencil 100 450
Paul 500 1950 rubber 350 450
Messy 2000 7050 car 7000 50
Messy 2000 7050 mouse 50 50
Mary 1500 1900 bag 1500 400
Mary 1500 1900 keyboard 400 400
Georghe 1000 6850 mouse 50 350
Georghe 1000 6850 ps 300 350
Georghe 1000 6850 tv 1500 350
Georghe 1000 6850 wheel 5000 350
You can use analytic functions rather than GROUP BY and aggregating:
select s.studentname,
s.tax,
invoiceamount,
SUM(d.amount) OVER (PARTITION BY s.invoiceno) AS inv_amt_calc,
d.product,
d.amount,
SUM(CASE WHEN c.code IS NOT NULL THEN d.amount END)
OVER (PARTITION BY s.invoiceno) AS taxexclude
from student s
INNER JOIN studentdetail d
ON s.invoiceno = d.invoiceno
LEFT OUTER JOIN specialcodes c
ON (c.code = d.code)
Note: You can (and should) calculate the invoice amount from the studentdetails table rather than duplicating the data in the student table and violating Third-Normal Form.
Which, for your sample data, outputs:
STUDENTNAME
TAX
INVOICEAMOUNT
INV_AMT_CALC
PRODUCT
AMOUNT
TAXEXCLUDE
Paul
500
1950
1950
rubber
350
450
Paul
500
1950
1950
pencil
100
450
Paul
500
1950
1950
bag
1500
450
Georghe
1000
6850
6850
tv
1500
350
Georghe
1000
6850
6850
wheel
5000
350
Georghe
1000
6850
6850
ps
300
350
Georghe
1000
6850
6850
mouse
50
350
Mary
1500
1900
1900
bag
1500
400
Mary
1500
1900
1900
keyboard
400
400
Messy
2000
7050
7050
mouse
50
50
Messy
2000
7050
7050
car
7000
50
If you really want a version using GROUP BY then:
SELECT s.studentname,
s.tax,
s.invoiceamount,
SUM(d.amount) OVER (PARTITION BY s.invoiceno) AS inv_amt_calc,
d.product,
d.amount,
t.taxexclude
FROM student s
INNER JOIN studentdetail d
ON s.invoiceno = d.invoiceno
LEFT OUTER JOIN (
SELECT invoiceno,
SUM(amount) AS taxexclude
FROM studentdetail
WHERE code IN (SELECT code FROM specialcodes)
GROUP BY
invoiceno
) t
ON s.invoiceno = t.invoiceno;
db<>fiddle here

Dynamic subtraction in SQL

I have a table structure like this:
|Account | MaxBalance | UsedAmount|
|--------|-------------|-----------|
Acc1 10000 2000
Acc2 20000 4000
Acc3 50000 2000
Acc3 50000 3000
Acc3 50000 8000
Acc4 20000 1000
Acc4 20000 5000
Acc5 5000 500
The output that I want is for same account usedAmount is dynamically deleted from new remainingAmount.
Account | MaxBalance | UsedAmount | Remaining
----------------------------------------------
Acc1 10000 2000 8000
Acc2 20000 4000 16000
Acc3 50000 2000 48000
Acc3 50000 3000 45000
Acc3 50000 8000 37000
Acc4 20000 1000 19000
Acc4 20000 5000 14000
Acc5 5000 500 4500
This is really cumulative sum -- and then subtraction using that. However, you need a column that specifies the ordering, so I'll assume you have one (otherwise the question doesn't make sense):
select t.*,
(maxbalance -
sum(usedamount) over (partition by account order by <ordering col>)
) as remaining
from t;
Here is a db<>fiddle showing that this does exactly what your question is asking for.

Assign Unique Row Number based on pattern

I have a table with the following fields
CourseID Amount17 Amount15 Amount13
100152 3000 2400 0
100204 3000 2400 0
100066 3000 2400 0
100066 3000 2400 1800
100067 3000 2400 1800
100343 3000 2400 1800
100126 3000 2400 1800
100022 3000 3000 0
100344 3000 3000 0
100050 3000 3000 0
100078 3000 3000 0
I would like to group matching three amount columns in a list. My desired output
CourseID Amount17 Amount15 Amount13 CourseList
100152 3000 2400 0 1
100204 3000 2400 0 1
100066 3000 2400 0 1
100066 3000 2400 1800 2
100067 3000 2400 1800 2
100343 3000 2400 1800 2
100126 3000 2400 1800 2
100022 3000 3000 0 3
100344 3000 3000 0 3
100050 3000 3000 0 3
100078 3000 3000 0 3
I have tried row_number over(order by ) but it does not seem to help. Tried using DenseRank but of no use.
I think you just want dense_rank():
select t.*,
dense_rank() over (order by amount17, amount15, amount13) as courselist
from t;

Select most recent entry in table by another column

I have 3 SQL tables. StudentTable, FeeAssociationTable and InvoiceTable.
StudentTable has primary key of AdmissionNumber, FeeAssociationTable has primary key of FeeAssociationID and InvioceTable has primary key InvoiceID.
The FeeAssociationTable takes AdmissionNumber and assign a fee to it, then while depositing fee the InvoiceTable takes AdmissionNumber and calculate all his fee and subtract from paid and the inserts in the dues.
The problem is; same AdmissionNumbercan have multiple row in InvoiceTable, "How can I can select and sum all recent dues of each AdmissionNumber(not repeating)."
Here is some data;
37 1 3000 January-2018 3000 0 2018-08-17
38 2 3000 January-2018 3000 0 2018-08-17
39 3 3000 January-2018 3000 0 2018-08-17
40 4 3000 January-2018 3000 0 2018-08-17
41 5 3000 January-2018 3000 0 2018-08-17
42 6 3000 January-2018 3000 0 2018-08-17
43 7 3000 January-2018 3000 0 2018-08-17
44 8 3000 January-2018 3000 0 2018-08-17
45 9 3000 January-2018 3000 0 2018-08-17
46 10 3000 January-2018 3000 0 2018-08-17
47 1 3200 June-2018 2500 700 2018-08-17
48 2 3200 June-2018 2500 700 2018-08-17
49 3 3200 June-2018 2500 700 2018-08-17
50 4 3200 June-2018 2500 700 2018-08-17
51 5 3200 June-2018 2500 700 2018-08-17
52 6 3200 June-2018 2500 700 2018-08-17
53 7 3200 June-2018 2500 700 2018-08-17
54 8 3200 June-2018 2500 700 2018-08-17
55 9 3200 June-2018 2500 700 2018-08-17
56 10 3200 June-2018 2500 700 2018-08-17
57 10 3700 July-2018 2500 1200 2018-08-17
58 9 3700 July-2018 2400 1300 2018-08-17
59 8 3700 July-2018 200 3500 2018-08-17
60 7 3700 July-2018 2000 1700 2018-08-17
61 1 3700 July-2018 1500 2200 2018-08-17
62 2 3700 July-2018 3100 600 2018-08-17
Expectation:
I want the most recent dues of each student without adding in the previous one.
For example:-
InvoiceId AdmissionNumber TotalFee Month Paid Dues Date
37 1 3000 January-2018 3000 0 2018-08-17
47 1 3200 June-2018 2500 700 2018-08-17
61 1 3700 July-2018 1500 2200 2018-08-17
There are 3 entries of AdmissionNumber 1 in the InvoiceTable. In the first one there are no due, but in the second entry there are Dues of 700, and in the third the dues of 2200 on AdmissionNumber 1.
The thing I want to do is select last one which can be done by this code given below:
SELECT Dues FROM InvoiceTable AS IT
WHERE IT.InvoiceID = (SELECT MAX(InvoiceID)
FROM InvoiceTable WHERE AdmissionNumber = 1)
This is for single I want list of recent dues of every student.
Thanks in Advance
Based on your follow up information, I believe the following will give you what you are looking for:
SELECT invoiceId, AdmissionNumber, Dues
FROM InvoiceTable AS IT
WHERE IT.invoiceId IN (SELECT MAX(invoiceId)
FROM InvoiceTable
GROUP BY AdmissionNumber)
ORDER BY AdmissionNumber ASC
They query you tried in your example was close, it just had to be adapted to work for the whole table and not a single AdmissionNumber.
Here is a demo of this working: SQL Fiddle

adding two columns in two tables having multiple layers

I am having two tables here from which I needed to add two columns.
table 1 table 2
1 ram 100 null 1 ram 100 1000
2 ram 200 1000 2 ram 200 null
3 ram 100 2000 3 ram 100 3000
4 ram 100 3000 4 ram 100 4000
5 ram 100 null 5 ram 100 5000
1 rahim 100 5000 1 rahim 100 null
2 ram 200 6000 2 ram 200 7000
3 ram 200 null 3 ram 200 8000
4 ram 200 null 4 ram 200 9000
5 rahim 100 9000 5 rahim 100 null
1 robert 100 10000 1 robert 100 11000
2 rahim 200 11000 2 rahim 200 12000
3 ram 300 12000 3 ram 300 null
4 rahim 400 13000 4 rahim 400 14000
5 robert 100 14000 5 robert 100 15000
result should be in the form:
1 ram 100 1000
2 ram 200 -1000
3 ram 100 1000
4 ram 100 1000
5 ram 100 5000
1 rahim 100 -5000
2 ram 200 1000
3 ram 200 8000
4 ram 200 9000
5 rahim 100 -9000
1 robert 100 1000
2 rahim 200 1000
3 ram 300 -12000
4 rahim 400 1000
5 robert 100 1000
You can use join with coalesce to remove the null values:
select t1.id, t1.somefield, t1.someint,
coalesce(t2.someint2,0)-coalesce(t1.someint2,0)
from table1 t1
join table2 t2 on t1.id = t2.id
and t1.somefield = t2.somefield
and t1.someint = t2.someint
SQL Fiddle Demo
Based on your input data, this joins on the first 3 columns. Not completely sure this is what you want, but should get you going in the correct direction.
I think try subtract table2.col4 with table1.col4.
SELECT a.col1,
a.col2,
a.col3,
NVL(a.col4, 0) - NVL(b.col4, 0) SUB
FROM table1 A
JOIN table2 B
ON A.col1 = b.col1
AND a.col2 = b.col2