Assign Unique Row Number based on pattern - sql

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;

Related

Cumulative over table rows with condition Oracle PL/SQL

I have two tables:
Employees:
employee_id field max_amount
3 a 3000
4 a 3000
1 a 1600
2 a 500
4 b 4000
2 b 4000
3 b 1700
ordered by employee, field, amount desc.
Amounts (pol, premia,field):
pol premia field **assign_to_employee**
11 900 a 3
44 1000 a 3
55 1400 a 4
77 500 a 3
88 1300 a 1
22 800 b 4
33 3900 b 2
66 1300 b 4
Assign Stats Table:
employee_id field max_amount true_amount remain
3 a 3000 2400 600
4 a 3000 1400 1600
1 a 1600 1300 300
2 a 500 0 500
4 b 4000 2100 1900
2 b 4000 3900 100
3 b 1700 0 1700
The output : assign_to_employee field (merged to amounts table).
Algoritem wise : The method is to assign pol's to employees until the premia needs to be added to the cumulative_sum is bigger then the max amount per employee listed in the employees table. You always start with the employess with most max amount until you cannot add any other pols to the employee.
I start with the employees with the grater max_amount per field.
I keep doing this until no pols remains to be assign.
Can you help me solve this?
Thank you.

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.

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

Dynamic Columns With Calculated Values

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

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