SQL update based on column in other table - sqlite

Using SQLite, I am trying to update three columns based on another table (two columns)
The three columns are (Table1):
'AgentCreatedID'
'AgentOwnedID'
'AgentSentID'
The other table (Table2) consists of 'AgentID' and 'Designation'.
If the ID in one of the three columns matches the 'AgentID' in the second table, I want the 'Designation' value to populate. This table is a list of ALL unique IDs and the corresponding designation. Each row of data has a Creator, Owner, and Sender. I need to see what designation that person is from.
In Access, this would look something like this for the first value. I would also need to add the other two values.
UPDATE Table1
LEFT JOIN Table2 ON Table1.AgentCreatedID = Table2.AgentID
SET raw.AgentCreatedID = [ Table2 ]![ Designation];
I am not sure what that ! command is or how it could be used in SQLite.

SQLite does not suport joins in an UPDATE statement.
You have to look up the new value with correlated subqueries:
UPDATE Table1
SET AgentCreatedID = (SELECT Designation
FROM Table2
WHERE AgentID = AgentCreatedID),
AgentOwnedID = (SELECT Designation
FROM Table2
WHERE AgentID = AgentOwnedID),
AgentSentID = (SELECT Designation
FROM Table2
WHERE AgentID = AgentSentID)

The exclamation mark is used to separate the worksheet name from the reference in that worksheet. Here is Microsoft's explanation of cell references.
Now that you know what [ Table2 ]![Designatio] means, you can simplify it to use only the column name.

Related

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.

Sqlite | How do I select records from two different tables using Case?

Edit
I would rather explicitly state my problem I'm facing rather than assuming the approach. There could be an easiest solution to my problem.
I need to select records by joining two different table based on the result from another table. And I have to use different joins based on the result from the first table.
If a particular record is present in the first table, I have two use inner join the first table whereas if it's not present, then I have to left join.
bool recordPresent = select exists (select * from firstTable where access_id = 13) as access
if (recordPresent)
results = select * from secondTable s left join firstTable f on f.access_id = s.access_id where f.access_id is null order by access_id
else
results = select * from secondTable s inner join firstTable f on f.access_id = s.access_id

SQLite: updating column from another table

I have a old table and a new table. what i need is to copy the uuId of the old table to the new Table.
im following some answers from other references but i can`t get the ideal answer.
the closest answer i found is this:
update table1
set table1.uuid =
(select table2.uuid from table2 where table1.itemDescription = table2.itemDescription)
when i execute this query, it only saves the 1st found uuid of the old table to all the entry in the new Table.
Sample Table2 (old table):
uuid|itemDescription
1|item1
2|item2
3|item3
Sample Table1 (new Table):
uuid|itemDescription
Null|item1
Null|item2
Null|item3
Desired Output:
uuid|itemDescription
1|item1
2|item2
3|item3
what happens:
uuid|itemDescription
1|item1
1|item2
1|item3
In SQLite, you must not use the table name in the SET clause:
update table1
set uuid =
(select table2.uuid from table2 where table1.itemDescription = table2.itemDescription);
Try like this :
UPDATE table1
SET table1.uuid = table2.uuid
FROM table2 WHERE table1.itemDescription = table2.itemDescription
No need for subquery, otherwise you need to link item description in outer query also

Update row with value from next row sqlite

I have the following columns in a SQLite DB.
id,ts,origin,product,bid,ask,nextts
1,2016-10-18 20:20:54.733,SourceA,Dow,1.09812,1.0982,
2,2016-10-18 20:20:55.093,SourceB,Oil,7010.5,7011.5,
3,2016-10-18 20:20:55.149,SourceA,Dow,18159.0,18161.0,
How can I populate the 'next timestamp' column (nextts) with the next timestamp for the same product (ts), from the same source? I've been trying the following, but I can't seem to put a subquery in an UPDATE statement.
UPDATE TEST a SET nextts = (select ts
from TEST b
where b.id> a.id and a.origin = b.origin and a.product = b.product
order by id asc limit 1);
If I call this, I can display it, but I haven't found a way of updating the value yet.
select a.*,
(select ts
from TEST b
where b.id> a.id and a.origin = b.origin and a.product = b.product
order by id asc limit 1) as nextts
from TEST a
order by origin, a.id;
The problem is that you're using table alias for table in UPDATE statement, which is not allowed. You can skip alias from there and use unaliased (but table-name prefixed) reference to its columns (while keeping aliased references for the SELECT), like this:
UPDATE TEST
SET nextts = (
SELECT b.ts
FROM TEST b
WHERE b.id > TEST.id AND
TEST.origin = b.origin AND
TEST.product = b.product
ORDER BY b.id ASC
LIMIT 1
);
Prefixing unaliased column references with the table name is necessary for SQLite to identify that you're referencing to unaliased table. Otherwise the id column whould be understood as the id from the closest[*] possible data source, in which case it's the aliased table (as b alias), while we're interested in the unaliased table, therefore we need to explicitly tell SQLite that.
[*] Closest data source is the one listed in the same query, or parent query, or parent's parent query, etc. SQLite is looking for the first data source (going from inner part to the outside) in the query hierarchy that defines this column.

Sqlite Query replacing a column with a column from another table

I have 2 tables, one is indexing the other.
I am querying Table#1, and it has one column (string) that has an ID in it that corresponds to a unique row in Table#2. Im trying to write a query in Sqlite that allows me to retrieve the value from Table#2 if the column value in Table#1 is not an empty string.
Kinda like:
"SELECT TMake,TModel,TTrim,IYear,[%q] AS TPart1 FROM AppGuide WHERE TPart1 != ''"
But instead of retrieving the Index value (TPart1) Id like to get the string from Table#2.
Is this possible?
Any help is appreciated.
You could use a correlated subquery:
SELECT TMake,
TModel,
...,
(SELECT stringvalue
FROM Table2
WHERE Table2.ID = Table1.TPart1)
FROM Table1
WHERE Table1.TPart1 != ''
However, these are rather slow to execute, so you'd better use a join (this returns exactly the same result):
SELECT Table1.TMake,
Table1.TModel,
...,
Table2.stringvalue
FROM Table1 LEFT JOIN Table2 ON Table1.TPart1 = Table2.ID
WHERE Table1.TPart1 != ''
If you don't want to get records from Table1 that have no matching Table2 record, drop the LEFT.

Resources