insert a column from one table to another with constraints - sql

I have 2 tables: legend and temp. temp has an ID and account ID, legend has advent_id, account_id and other columns. ID in temp and advent_id in legend are similar. account_id column is empty and I want to import the relevant account_id from temp to legend. I am using PostgreSQL.
I am trying the following query, but it is not working as I am expecting. New rows are getting created and the account_id's are getting added in the new rows, not to the corresponding advent_id.
insert into legend(account_id)
select temp.account_id
from legend, temp
where legend.advent_id=temp.id;
It is inserting the account_id in the wrong place, not to the corresponding advent_id.
I am using the following query to check:
select advent_id, account_id from legend where account_id is not null;
What exactly is the problem in my insert query?

If you are trying to modify existing rows, rather than add rows, then you need an UPDATE query, not an INSERT query.
It's possible to use joined tables as the target of an UPDATE; in your example:
UPDATE legend
JOIN temp
SET legend.account_id = temp.account_id
WHERE(temp.id = legend.advent_id);

Related

Repeating Max(timestamp) value for all the duplicate ID rows in bigquery

This might be simple, but I am having troubles resolving this issue
I have a table with following columns and data :
There are multiple entries for an id with different updateTimestamp, I want to identify the max timestamp and repeat that value for all the duplicate ids in the table. Also, the table is large and I do not want to query it multiple times(process is complex).
Here is what I am expecting the output to look like
You need to find maximum of update timestamp for each ID and update the table using ID column. Something like
update <table_name> tgt
set tgt.max_updatetimestamp = src.maxstamp
from (select id, max(updatetimestamp) as maxstamp from <tablename> group by 1) src
where tgt.id = src.id;

Queries with functions that return many rows

I've a table with a geometry column. Those geometries are often multipolygons or multilinestrings and I would like to split them into their constituent parts without duplicating the other data in there rows. At the moment i use the following:
CREATE TABLE newTable AS SELECT index, ST_Dump(geometry) AS geometry FROM initialTable
This works without a problem and produces newTable with polygons and linestrings and a reference column for it's row in the initialTable containing other relevent info.
I would however like to incorporate progress tracking found here as the above statement can take some time.
I would therefore like to split the above statement into 1) creating the table 2) populating the table
The first is easy, but populating the table escapes me as one multilinestring row can create many linestrings rows.
Any assistance would be greatly appreciated.
Use ST_Dump in a SELECT and redirect the result set to the INSERT statement, e.g.:
CREATE TABLE newTable (gid int, geom geometry(linestring,4326));
INSERT INTO newtable
SELECT (ST_Dump(geom)).path[1],(ST_Dump(geom)).geom
FROM initialTable;

How to append unique values from temp_tbl into original_tbl (SQL Server)?

I have a table that I'm trying to append unique values to. Every month I get list of user logins to import into this table. I would like to keep all the original values and just append the new and unique values onto the existing table. Both the table and the flatfile have a single column, with unique values, built like this:
_____
login
abcde001
abcde002
...
_____
I'm bulk ingesting the flat file into a temp table, with this:
IF OBJECT_ID('tempdb..#FLAT_FILE_TBL') IS NOT NULL
DROP TABLE #FLAT_FILE_TBL
CREATE TABLE #FLAT_FILE_TBL
(
ntlogin2 nvarchar(15)
)
BULK INSERT #FLAT_FILE_TBL
FROM 'C:\ImportFiles\logins_Dec2021.csv'
WITH (FIELDTERMINATOR = ' ');
Is there a join that would give me the table with existing values + new unique values appended? I'd rather not hard code a loop to evaluate it line by line.
Something like (pseudocode):
append unique {login} from temp_tbl into original_tbl
Hopefully it's an easy answer for someone out there.
Thanks!
Poster on Reddit r/sql provided this answer, which I'm pursuing:
Merge statement?
It looks like using a merge statement will do exactly what I want. Thanks for those who already posted replies.
You can check if a record exists using 'EXISTS' clause and insert if it doesn't exist in the target table. You can also use MERGE statement to achieve the same. Depending on what you want to do to the existing records in the target table, you can modify the Merge statement. Here since you only want to insert new records, you need to specify only what you want to do when a new record comes in. Here is an example
MERGE original_tbl T
USING temp_tbl S
ON T.login = S.login
WHEN NOT MATCHED THEN
INSERT (login)
VALUES(S.login)
Another solution would be to left join the target table to the temp table and insert only when the record doesn't exist.
INSERT INTO original_tbl(login)
SELECT S.Login
FROM temp_tbl S
LEFT JOIN original_tbl T
ON S.Login = T.Login
WHERE T.Login IS NULL

Why is 'insert into select' statement in SQL inserting as a new row and not inserting correctly?

I have table 1.
I have another empty table 2 with the following columns.
I want to insert into table 2 by selecting from table 1 - so I write the query as:
insert into table2(employee,id,zone,url)
select employee, id, zone, concat('https://',employee,'.com/',id,'?',zone)
from table1
Now my table 2 looks like this,
Now for the authcode column, I do the following and insert it into the table2.
insert into table2(authcode)
SELECT CONVERT(VARCHAR(10),HASHBYTES('MD5', substring(URL,8,100)),2)
from table2.
But the insert happens differently like this AS AN ENTIRE NEW SET OF ROWS.
Can someone help me to insert the last column to the corresponding rows instead of it creating a new one?
What you should be doing is UPDATE the table to fill the column authcode, but you could do it all in 1 step while you are inserting the rows:
insert into table2(employee,id,zone,url, authcode)
select
employee,
id,
zone,
concat('https://',employee,'.com/',id,'?',zone),
CONVERT(VARCHAR(10),HASHBYTES('MD5', substring(concat('https://',employee,'.com/',id,'?',zone),8,100)),2)
from table1
or if you want to update:
update table2
set authcode = CONVERT(VARCHAR(10),HASHBYTES('MD5', substring(URL,8,100)),2)
where authcode is null
The result you are seeing is the intended behavior for an INSERT statement. It will always insert new rows.
If you want to modify existing rows your need to use an UPDATE statement.
You can either modify your INSERT to look like what #forpas has posted to get all this work done in one step. Another option is to modify the second INSERT to be an UPDATE like the following:
update table2
set authcode = CONVERT(VARCHAR(10),HASHBYTES('MD5', substring(URL,8,100)),2)

How to Update a Single record despite multiple Occurances of the same ID Number?

I have a table that looks like the below table:
Every time the user loan a book a new record is inserted.
The data in this table is derived or taken from another table which has no dates.
I need to update this tables based on the records in the other table: Meaning I only need to update this table based on what changes.
Example: Lets say the user return the book Starship Troopers and the book return is indicated to Yes.
How do I update just that column?
What I have tried:
I tried using the MERGE Statement but it works only with unique rows of data, meaning you get an error if the same ID appears more than once.
I also tried using a basic UPDATE Statement and a JOIN but that's not going well.
I am asking because I have ran out of ideas.
Thanks for reading
If you need to update BooksReturn in target table based on the same column in source table
UPDATE t
SET t.booksreturn = s.booksreturn
FROM target t JOIN source s
ON t.userid = s.userid
AND t.booksloaned = s.booksloaned
Here is SQLFiddle demo
You can do this by simple Update & Insert statement.....
Two table A & B
From B you want to insert data into A if not exists other wise Update that data....
,First Insert into temp table....
SELECT *
INTO #MYTEMP
FROM B
WHERE BOOKSLOANED NOT IN (SELECT BOOKSLOANED
FROM A)
,Second Check data and insert into A.
INSERT INTO A
SELECT *
FROM #MYTEMP
And at last write one simple update statement which update all data of A. If any change then it also reflect to that data otherwise data as it is.
You can also update from #MYTEMP table.