INSERT INTO and insert NULL in PostgreSQL - sql

Update:
This question has no value and can be deleted. The syntax shown in the question actually works well and is likely the best approach.
I'd like to insert NULL into one column as part of a "select into". In the example below, I try to copy columns a and b from table_1 to table_2, and in the same query, insert NULL into table_2.c
I've tried this:
INSERT INTO table_2 (a, b, c)
SELECT a, b, NULL
FROM table_1
But I get ERROR 42601 (syntax_error) syntax error at or near "NULL".
Appreciate any guidance on this.

Nonsense. Your statement is syntactically correct.
None of the suggestions here are necessary. The error you report should not occur.
Also, SELECT INTO (like you wrote in error) is an unrelated command - the use of which is discouraged in favor of CREATE TABLE AS.
Typically, you can just omit columns that shall be NULL from the target list - unless a different default value is set for the column. But it's typically bad style to omit the target column list altogether (exceptions apply).
INSERT INTO table_2 (a, b)
SELECT a, b
FROM table_1;
If column table_2.c has no different DEFAULT value in the table definition, it defaults to NULL. To be precise:
How to use default value of data type as column default?
Shorter; but there is nothing wrong with your original query. In fact, it's the best way.

Related

How to UPDATE from a Select in sql?

A little personal project i'm doing, kinda new in sql.
Lets say i have a table with multiples columns, but i want to work with 2 for this request: CODE and VALUE
Basically, the codes are like this : 1_A, 1_B, 1_C, 2_A, 2_B, 2_C, 3_A, 3_B, 3_C, etc... They are already created.
What i want to do is replace the VALUE from the C codes with the A codes: 1_A -> 1_C, 2_A->2_C, and so on. Without touching the other colmuns
What i thougt so far is :
update TABLE set Value = (select value from TABLE from CODE like '%A%') where CODE like '%C%'
But how do make sure that the Value associated with the code X_A gets copied into X_C specifically ? Like, so 1_A gets copied into 1_C and not 2_C. Maybe it has to do with JOIN, but honestly i don't get how those work yet
Edit : it's on oracle
If you're looking to copy all the A values to C values, you should use an insert statement, not an update statement. This can be with the insert-select construct:
INSERT INTO mytbale (value)
SELECT REPLACE(value, 'A', 'C')
FROM mytable
WHERE value LIKE '%A'

Searching for a value from all of my SQL table

I am using PostgreSQL and I would like to get row/rows(depending on the query), by giving it a value and searching all of the available columns of my table.
How would I go about checking every column for a value ? I also am looking at checking for different types of values
If the columns are a and b and the text you are searching for is 'test' then something like this will do the trick:
select *
from table1
where 'test' in (a, b);
Note: this will only work if all your columns have the same datatype and the same datatype with the value you search for.

How to know which column has changed on UPDATE?

In a statement like this:
update tab1 set (col1,col2)=(val1,val2) returning "?"
I send whole row for update on new values, RETURNING * gives back the whole row, but is there a way to check which exactly column has changed when others remained the same?
I understand that UPDATE rewrites the values, but maybe there is some built-in function for such comparison?
Basically, you need the pre-UPDATE values of updated rows to compare. That's kind of hard as RETURNING only returns post-UPDATE state. But can be worked around. See:
Return pre-UPDATE column values using SQL only
So this does the basic trick:
WITH input(col1, col2) AS (
SELECT 1, text 'post_up' -- "whole row"
)
, pre_upd AS (
UPDATE tab1 x
SET (col1, col2) = (i.col1, i.col2)
FROM input i
JOIN tab1 y USING (col1)
WHERE x.col1 = y.col1
RETURNING y.*
)
TABLE pre_upd
UNION ALL
TABLE input;
db<>fiddle here
This is assuming that col1 in your example is the PRIMARY KEY. We need some way to identify rows unambiguously.
Note that this is not safe against race conditions between concurrent writes. You need to do more to be safe. See related answer above.
The explicit cast to text I added in the CTE above is redundant as text is the default type for string literals anyway. (Like integer is the default for simple numeric literals.) For other data types, explicit casting may be necessary. See:
Casting NULL type when updating multiple rows
Also be aware that all updates write a new row version, even if nothing changes at all. Typically, you'd want to suppress such costly empty updates with appropriate WHERE clauses. See:
How do I (or can I) SELECT DISTINCT on multiple columns?
While "passing whole rows", you'll have to check on all columns that might change, to achieve that.

Oracle Selecting Columns with IN clause which includes NULL values

So I am comparing two Oracle databases by grabbing random rows in database A, and searching for these rows in database B based off their key columns. Then I compare the rows which are returned in java.
I am using the following query to find rows in database B using the key columns from database A:
select * from mytable
Where (Key_Column_A,Key_Column_B,Key_Column_C)
in (('1','A', 'cat'),('2','B', 'dog'),('3','C', ''));
This works just fine for the first two sets of keys, but the third key('3','C', '') does not work because there is a null value in the third column. Changing the statement to ('3','C', NULL) or changing the SQL to
select * from mytable
Where (Key_Column_A,Key_Column_B,Key_Column_C)
in ((('1','A', 'cat'),('2','B', 'dog'),('3','C', ''))
OR (Key_Column_A,Key_Column_B,Key_Column_C) IS NULL);
will not work either.
Is there a way to include a null column in an IN clause? And if not, is there a way to efficiently do the same thing? (My only solution currently is to create a check to make sure there are no nullable columns in my keys which would make this process rather unefficient and somewhat messy).
You can use it this way. I think it would work.
select * from mytable
Where (NVL(Key_Column_A,''),NVL(Key_Column_B,''),NVL(Key_Column_C,''))
in (('1','A', 'cat'),('2','B', 'dog'),('3','C', ''));
I am not sure about this (Key_Column_A,Key_Column_B,Key_Column_C) IS NULL. Wouldn't this imply that all of the columns (A,B,C) are NULL ?

sqlite data from one db to another

I have 2 sqlite databases, and I'm trying to insert data from one database to another. For example, "db-1.sqlite" has a table '1table' with 2 columns ('name', 'state'). Also, "db-2.sqlite" has a table '2table' with 2 columns ('name', 'url'). Both tables contain a list of 'name' values that are mostly common with each other but randomized, so the id of each row does not match.
I want to insert the values for the 'url' column into the db-1's table, but I want to make sure each url value goes to its corresponding 'name' value.
So far, I have done this:
> sqlite3 db-1.sqlite
sqlite> alter table 1table add column url;
sqlite> attach database 'db-2.sqlite' as db2;
Now, the part I'm not sure about:
sqlite> insert into 1table(url) select db2.2table.url from db2.2table where 1table.name==db2.2table.name
If you look at what I wrote above, you can tell what I'm trying to accomplish, but it is incorrect. If I can get any help on the matter, I'd be very grateful!!
The equality comparison operator in SQL is =, not ==.
Also, I suspect that you should be updating 1table, rather then inserting in it.
Finally, your table names start with digits, so you need to escape them.
This SQL should work better:
update `1table`
set url = (select db2.`2table`.url
from db2.`2table`
where `1table`.name = db2.`2table`.name);