I would like to take an existing TEXT field/row and append to it with sqlite3. I'm finding it somewhat difficult, I've seen some stuff with "upsert."
SQLite - UPSERT *not* INSERT or REPLACE
The specific database I'm working with has no relational connections to any other tables.
Assuming the ideal (pseudo code) UPDATE Table APPEND row values(" text")
assuming row contains "my " I would like it to result in "my text"
Ideally I would like to do this in a single query, but until then I'm left to selecting and using update set
You can use the current values of columns in an update:
UPDATE yourtable SET somecol = somecol || 'text' WHERE somecondition;
Related
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
I am using pgadmin4 (version 2.1) and I'm attempting to remove some legacy data from a table without deleting rows with specific words in the description?
Basically I'm attempting to do something like this:
DELETE FROM schema.table
WHERE column_description = all data
EXCEPT FOR 'specific word'
Any ideas?
Be sure to backup your data before attempting any deletes. But the idea would be:
DELETE FROM schema.table
WHERE column_description IS DISTINCT FROM 'specific word';
This does not delete NULL values. If the column could have NULL values, you will want those deleted too. So a better construct is:
DELETE FROM schema.table
WHERE column_description <> 'specific word';
Or, if the pattern could be part of the description, use NOT LIKE:
DELETE FROM schema.table
WHERE column_description NOT LIKE '%specific word%';
I have this excel table(it's just for the example):
and i have in the SQL table just with the colors.
i want to insert new column with the numbers like:
insert into table colors
set number = 'c'
where color = 'RED'
but i have 1500 records to add and i can't do it like this..
how can i do it?
thanks
First, you need to a add column in your SQL table (let's call it sql_table). I am assuming the colors in your excel table are a subset of the colors in your sql_table.
alter table sql_table
add color_id varchar(100) --change datatype/length as desired
Then you could bulk upload that file into SSMS as a new table (during upload/import make sure to set datatypes to be the same as your sql_table (let's call this new table excel_table)
Finally, update your sql_table by joining on to your excel_table. I am assuming the sql_table has 1 row per color.
update sql_table a
join excel_table b on a.color = b.color
set a.color_id = b.color_id;
If you wish, you can drop that excel_table since your sql_table is updated
You shouldn't need to know the database to write an SQL insert OR update. SQL is universal. Only flavors like MySql and T-SQL include language components foreign to SQL.
https://www.mysqltutorial.org/mysql-insert-statement.aspx
Updates
Only saw your actual question after reading the comments. First, create an Excel column which concatenates the update script.
=concatenate("update colors set number = '", B1, "' where color = '", A1, "'")
Creates
First, create an Excel column which concatenates the values into the format:
('color', 'number'),
=concatenate("('", A1, "', '", B1, "'),")
Be aware with SQL Server, you can only insert 1000 rows at a time.
insert into colors values
(paste rows here)
(remove comma from last line)
You only need to specify the table structure in the query if your input data is not in the same form as the table, which you can control.
what i did was so easy,
i just copy the data from the excel to SSMS:
1. right click--> edit 200 top rows. and i past the data.
the i did what u write:
update sql_table a
join excel_table b
on a.color = b.color
thanks to you all
CURSOR text IS
SELECT *
FROM DATA
CURSOR MATCHES IS
SELECT NAME
FROM DATA
INTERSECT
SELECT DESCRIPTION
FROM my_table
BEGIN
FOR i IN text
OPEN MATCHES
FETCH MATCHES INTO MATCH
CLOSE MATCH
IF i IN MATCH
THEN
UPDATE my_table
SET col1 = correlating_new_column1, col2 = correlating_new_column2, col3 = correlating_new_column3
WHERE table_im_trying_to_populate.code = my_seq.curval
ELSE
INSERT INTO TABLE_IM_TRYING_TO_POPULATE(CODE, NAME, DESCRIPTION, col1, col2, col3)
VALUES(my_seq.nextval, other_name, other_description, correlating_new_column1, correlating_new_column2, correlating_new_column3)
END IF;
END LOOP;
Basically I am trying to take an explicit cursor I made that is a select statement of a table and then do a line by line loop of that and put it into my other existing table. If it comes across a name in my other exisiting table it will update some of the columns. Else it inserts the whole record into that table. I am attempting to use sequence to update the 'code' column so that it updates where the code from the other existing table = my_seq.curval. Then for the inset it just goes to the next val. I know this is complicated but Im really just trying to see if I have the setup correct. Just started using sql developer for oracle not to long ago.
There are a huge number of problems with your code. However, it looks like what you're trying to do can be achieved with a single MERGE statement, along the lines of:
merge into table_im_trying_to_populate tgt
using data_table src
on (tgt.name = src.other_name
and tgt.description = src.other_description)
when matched then
update set tgt.col1 = src.correlating_new_column1,
tgt.col2 = src.correlating_new_column2,
tgt.col3 = src.correlating_new_column3
when not matched then
insert (tgt.code, tgt.name, tgt.description, tgt.col1, tgt.col2, tgt.col3)
values (my_seq.nextval, src.other_name, src.other_description, src.correlating_new_column1, src.correlating_new_column2, src.correlating_new_column3);
This assumes that the other_name and other_description columns in the data table is unique. I've also had to guess at what the join condition should be, since the join condition you had in your example update statement (table_im_trying_to_populate.code = my_seq.currval) didn't make any sense - you don't use currval to join against as a general rule, since it isn't populated unless you've previously pulled a value from the sequence in the same session.
If this doesn't match what you're trying to do, please update your question with some sample data in both tables and the expected output, and we should be able to help you further.
I have a database full of simple note data, with columns for title, due date, priority, and details. There is also a _id column PRIMARY KEY int.
Say I have a note in the table already with some data filled and the rest null. I also have a set of data that will fill all those fields.
Is there a way that I can only write data to the fields that are NULL?
I can't overwrite existing data, but I'd like to add data to NULL columns.
I know the rowId of the target row.
If my target row had rowId of 5, I could do something like this:
UPDATE SET duedate='some date', priority='2', details='some text' WHERE _id=5
But that would overwrite all the data in that row, and I don't want to lose any data that might be there. How can I change this statement to avoid writing to non-null fields?
Suppose you start with
CREATE TABLE "t" ("a" , "b" , "c" );
INSERT INTO "t" ("a", "c") VALUES (1, 3);
Then
update t set a = coalesce(a,9), b = coalesce(b,10), c = coalesce(c,11);
Will update only the null values, ie. only column B will be set to 10. A and C will be left alone because they contain values.
Coalesce means pick the first item in the list that is not null.
The UPDATE statement only changes the fields you specify in the SET clause. If there are fields whose value you want left unmodified, then simply don't specify those fields in the SET clause.
Put another way, UPDATE doesn't write to all fields in the table - just the fields you specify for the rows you select with the WHERE clause.
If you simply don't know if the existing data is NULL or not, you can set the values using IFNULL(CurrentValue, NewValueIfNull). E.g.
UPDATE SET due_date=IFNULL(due_date, "some date") ... etc..
This will merge your new values into the row where there NULL values, and leave non-NULL values as they were.
See SQL Lite, IFNULL
How about:
UPDATE SET duedate='some date' WHERE _id=5 and duedate is null;
UPDATE SET priority='2' WHERE _id=5 and priority is null;
UPDATE SET details='some text' WHERE _id=5 and priority is null;
If you use Mysql, you can lookup IF()-then you can create a one liner. I think you can do something with similar in Oracle with case...