How to fetch first occurance of most active row row in job table with specific deptid, - peoplesoft

Eg : Emplid 001 most effective dated row (say 01/01/2013 )is active and belongs to deptid 101.Suppose If he has two more rows prior with same deptid say one on 10/12/2012 and 01/12/2012, Then i needs to retrieve 01/12/2012 rows.So it should be the first row of continous occurances, In case if i have row with 05/12/2012 with other deptid (102), In that case my query should return 10/12/2012 rows, Please help on this

Though not with a left join, this uses a sub-select on minimum effective date to get the data you need - the trick to get the min effdt by deptid is putting the deptid in the sub-select. Note that empl_rcd_nbr is usually used as a limiter in the sub-select (and job2.empl_rcd_nbr - job.empl_rcd_nbr) but you didn't have it in your original select. If you get dup rows, check your empl_rcd_nbr value since it is a primary key:
select job.emplid, job.effdt, job.deptid
from ps_job job
where job.effdt = (select Min(job2.effdt)
from ps_job job2
where job2.emplid = job.emplid
and job2.deptid = job.deptid)
order by job.emplid

To achieve what you need, you will have to pick up the min(effdt) row with deptid same as the deptid of the current max(effdt) row and also, there should not exist a row > the min(effdt) with deptid <> deptid of the min(effdt) row.
A query satisfying the above conditions should help you with your result set.

Related

Problem inserting database row using last row in sqlite

I'd like to be able to do the following initially and also at anytime.
insert into balance (closing_amount, opening_amount, created, tx_id)
select closing_amount + :value, closing_amount, :date, :tx_id from balance order by id desc limit 1
Basically I'm inserting by using previous values. But if there are no values to begin with, nothing gets inserted.
I could use a union to which works the first time but duplicates on subsequent inserts.
I want to avoid two trips. Is there a way to do this?
Also, the tx_id will always be unique.
I think you want something like this:
insert into balance (closing_amount, opening_amount, created, tx_id)
select coalesce(max(closing_amount), 0) + :value,
coalesce(max(closing_amount), 0),
:date,
:tx_id
from (
select closing_amount
from balance
order by tx_id desc
limit 1
) t;
You only need the last closing_amount, so max(closing_amount) from the subquery, which returns 1 row or none at all, will return that closing_amount or null respectively.
See a simplified demo.

Result of SELECT MAX(id) is null

On the database open, I inserted 5 records into the Expense table. Then I removed all 5 records one by one.
And before I insert new entry I check max inserted id. For some reason it's null. What's wrong?
var result = await db.rawQuery("SELECT MAX(id) as last_inserted_id FROM Expense");
final maxID = result.first["last_inserted_id"];
print('maxID:$maxID'); //maxID:null
If there are no rows in the table, there is no maximum defined. What you rather should do is look for the ID sequence number of the table to find out what the next ID will be. That information is usually stored in some meta table of the DB.
SELECT seq FROM SQLITE_SEQUENCE WHERE name='Expense';

Delete only one column from the Target table even if there are multiple similar columns (Teradata)

I came across a situation where i have to delete a column from a table based on a condition from other table
Let me break it down to you!
There is a master table called MORTALITY (containing info regarding deceased individuals)
And another table called INC_MORTALITY (incremental mortality) table which is refreshed on a weekly basis
Note: Both the tables have similar format
So this week’s new records, containing both additional deceased individuals as well as updates of old data for previously delivered records. This is a single file with a column (OP_DIRECTIVE) specifying if it is an “add” or “delete” record.
Processing Weekly Files
To incorporate the weekly update file, we need to execute the following steps in order.
1. Delete rows in the master table which have a OP_DIRECTIVE = 'D' as the operation in the weekly update. For a given delete row, you should delete a single row in the master table which matches the delete record on all fields aside from the “D” operation column. Warning: please ensure you only delete, or mark as deleted, one record, even if more than one historical record fully matches this new delete record.
2. Add rows in the master table which appear in the “Add” file.
Upon completion of these steps, your master table should be the most up to date master of deaths.

(Note: THESE TABLES DOES NOT HAVE PRIMARY KEYS)
SO WHAT I TRIED:
DEL FROM MORTALITY MI
WHERE MI.DATA_SOURCE = INC_MORTALITY.DATA_SOURCE
AND MI.DD_IMP_FLAG = INC_MORTALITY.DD_IMP_FLAG
AND MI.DOB = INC_MORTALITY.DOB
AND MI.DOD = INC_MORTALITY.DOD
AND MI.DEATH_VERIFICATION = INC_MORTALITY.DEATH_VERIFICATION
AND MI.GENDER_PROBABILITY = INC_MORTALITY.GENDER_PROBABILITY
AND MI.GENDER = INC_MORTALITY.GENDER
AND MI.TOKEN_1 = INC_MORTALITY.TOKEN_1
AND MI.TOKEN_2 = INC_MORTALITY.TOKEN_2
AND MI.TOKEN_4 = INC_MORTALITY.TOKEN_4
AND MI.TOKEN_5 = INC_MORTALITY.TOKEN_5
AND MI.TOKEN_7 = INC_MORTALITY.TOKEN_7
AND MI.TOKEN_16 = INC_MORTALITY.TOKEN_16
AND MI.TOKEN_KEY = INC_MORTALITY.TOKEN_KEY
AND INC_MORTALITY.OP_DIRECTIVE = 'D'
The above Delete statement will delete all the rows satisfying the conditions, my requirement is to delete only one record even if more than one historical record fully matches this new delete record,
and if i include ROW NUMBER() stmt like below my DELETE stmt is not working
QUALIFY ROW_NUMBER() OVER (PARTITION BY MI.DATA_SOURCE,MI.DOB,MI.DOD
ORDER BY MI.DOD DESC ) = 1
Any suggestions on how to approach this scenario, Thanks!!
Approach to solution: Copy unmatched rows to a work table, then truncate the original table and replace with contents of the work table. One way to identify unmatched rows would be to tag each of the input rows in a set of duplicates with a unique number, something like this:
INSERT work_table SELECT MI.col1, MI.col2, ...
FROM
(SELECT M.*,
ROW_NUMBER() OVER (PARTITION BY <join cols> ORDER BY <some col(s)>) AS ROWNUM
FROM MORTALITY M) MI
LEFT JOIN
(SELECT I.*,
ROW_NUMBER() OVER (PARTITION BY <join cols> ORDER BY <some col(s)>) AS ROWNUM
FROM INC_MORTALITY I
WHERE OP_DIRECTIVE='D') INC
ON MI.join_col1 = INC.join_col1
AND MI.join_col2 = INC.join_col2
...
AND MI.ROWNUM = INC.ROWNUM
WHERE INC.ROWNUM IS NULL /* "anti-join" keeps only unmatched rows */
;
DELETE FROM MORTALITY;
INSERT MORTALITY SELECT * FROM work_table;
If INC_MORTALILTY never has duplicates, then you can eliminate numbering that relation and change the last join condition to MI.ROWNUM = 1 and use one of the other JOIN columns for the NULL check.

Show first n rows sorted by one column but they should be unique by another column (SQLite, Android Room)

A simple select * from mytable will return below rows. I don't know how to draw table in post so I am adding the image
As I mentioned in the question title:
(i) show first n rows sorted by one column (can be achieved using order by)
(ii) but they should be unique by another column (unique by collectionID column)
select * from mytable
order by lastAccessTime DESC;
this sorts the table in descending order according to their lastAccessTime as shown in below image:
Now I want to filter these rows according to their collectionID. So only 1 row per collectionID. I have added the image. The strikethrough rows should be removed.
Also, First n rows (lets say 30) should be returned.
I am using Android Room ORM which uses SQLite but to get the desired result set I have to write the correct query.
I think you need a window function filter here. Which will assign a row number based on collectionID and then you can just fetch only 1 row per collectionID. You may give a try to -
SELECT *
FROM (SELECT *, ROW_NUMBER() OVER(PARTITION BY collectionID ORDER BY ID DESC) RN
FROM mytable) T
WHERE RN = 1
LIMIT 30;
The key idea is to "filter" the data with one query which is the source of another query. A window function can be used as in the other answer, but a basic sub-query is also sufficient:
SELECT *
FROM mytable
INNER JOIN
(SELECT Max(id) AS singleID, collectionID
FROM mytable
GROUP BY collectionID) AS filter
ON mytable.id = filter.singleID
ORDER BY lastAccessTime DESC
LIMIT 30;

sqlite shift rowid in multiple records

Hello i have an sqlite db with many records like 10540 record they are ordered by creation time , i want to shift like a record in the middle and like to do it automatically
for example :
select * from table1 where id >= 8521;
UPDATE Table1 SET id = id +1 ;
does not work i get Error: Result: UNIQUE constraint failed:
so i want to shift up all records from 8521 to the last record and get place in the 8520 place for example so i can insert my record in that place of table .
even the
id = select max(id)+1
does not work how can i increment the id from last record to the needed record so i can put a place in the records db
A simple update statement would fail, as it would try to create duplicate values in the primary key.
What you can do is this:
First update the column to the negatives of the values they should have:
update table1
set id = -(id + 1)
where id > 8520;
Now there are no duplicates and you just need to update again to the positive values:
update table1
set id = -id
where id < 0;
This will do the trick, but any kind of updating the primary key is not a recommended practice

Resources