How to copy an sql column based on foreign key? - sql

How do I run the following query
INSERT INTO table1
SELECT sourceId
FROM table2
WHERE table2.id = table1.productId
given that table2 has an id column and a sourceId column (and few others) and table1 already contains productId and I want to copy the sourceId column into the table as well?
The error message I'm getting with this query is simply "Unknown column 'table1.productId' in where clause", but if I include table1.productId in the SELECT and table1 on the FROM row, I get the "Column count doesn't match value count at row 1" error.
Any idea how to fix up the query?

when you are inserting into a table, you have to specify what to insert in all columns of that table. Should look like this:
INSERT INTO table1 (column1, column2, column3, ...)
SELECT value1, value2, value3, ...
FROM table2
WHERE ...;
But in your case since you said table1 already contains productId, you probably should do an UPDATE and not an INSERT
UPDATE table1 t1
SET t1.sourceId =
(SELECT sourceId
FROM table2
WHERE table2.id = t1.productId);
If this works for you, you can improve on it with JOINs

The select part is supposed to work stand-alone, so you must select from table1 in that part, if you want to refer to its rows.
INSERT INTO table1
SELECT sourceId
FROM table2
WHERE table2.id IN (SELECT productId FROM table1);

Related

Update table if exist or insert if not

I have 2 SQL tables with same column label, Table1 and Table2.
I want to update Table1 with value of Table2 if there is a same value for an attribute.
The tables has CODE, POSITION, DESCRIPTION as columns.
I do this:
UPDATE Table1
SET CODE = Table2.CODE,
POSITION= Table2.POSITION
FROM Table2
WHERE DESCRIPTION = Table2.DESCRIPTION
It works, but if in the DESCRIPTION Value of Table2 is not present into Table1, I want to insert the entire row, in other words I need to do something like:
UPDATE IF DESCRIPTION EXISTS
ELSE INSERT
How can I do this?
You can do this from first-principals in 2 steps
Update the existing values like you have done:
UPDATE Table1
SET
CODE= t2.CODE,
POSITION= t2.POSITION
FROM Table1 t1
INNER JOIN Table2 t2 ON t1.DESCRITPION = t2.DESCRITPION
Then you can insert the missing records
INSERT INTO Table1 (CODE, POSITION, DESCRITPION)
SELECT CODE, POSITION, DESCRITPION
FROM Table2 t2
WHERE NOT EXISTS (SELECT DESCRITPION
FROM Table1 t1
WHERE t1.DESCRITPION = t2.DESCRITPION)
Most RDBMS have a MERGE statement that allows you to combine these two queries into a single atomic operation, you'll need to check the documentation for your vendor, but an MS SQL Server MERGE solution looks like this:
MERGE INTO Table1 AS tgt
USING Table2 AS src
ON tgt.DESCRITPION = src.DESCRITPION
WHEN MATCHED
THEN UPDATE SET CODE= src.CODE,
POSITION= src.POSITION
WHEN NOT MATCHED THEN
INSERT (CODE, POSITION, DESCRITPION)
VALUES (src.CODE, src.POSITION, src.DESCRITPION)
An additional benefit to the MERGE clause is that it simplifies capturing the changed state into the OUTPUT clause which allows for some complex logic all while keeping the query as a single operation without having to manually create and track transaction scopes.

Hive - cannot recognize input 'insert' in select clause

Say I've already created table3, and try to insert data into it using the following code
WITH table1
AS
(SELECT 1 AS key, 'One' AS value),
table2
AS
(SELECT 1 AS key, 'I' AS value)
INSERT TABLE table3
SELECT t1.key, t1.value, t2.value
FROM table1 t1
JOIN table2 t2
ON (t1.key = t2.key)
However, I got an error as cannot recognize input 'insert' in select clause. If I simply delete the insert sentence, then the query runs just fine.
Is this a syntax problem? Or I cannot use with clause to insert?
Use INTO or OVERWRITE depending on what you need:
INSERT INTO TABLE table3 --this will append data, keeping the existing data intact
or
INSERT OVERWRITE TABLE table3 --will overwrite any existing data
Read manual: Inserting data into Hive Tables from queries

sql oracle using update

I need to take data from one table to add to another table.
I got two SQL's:
SQL1:
select * from table1;
SQL2:
select * from table2 where coloumn1 = table1.coloumn6 (number)
table1 looks like:
For better understanding we call each coloumn coloumn1, coloumn2, ... coloumn9
table2 looks like:
For better understanding we call each coloumn coloumn1, coloumn2, ... coloumn13
What should happen in text
My SQL has to take the value from table1.coloumn6 (number) - checking if this value is given in table2.coloumn1
select * from table2 where coloumn1 = table1.coloumn6 (SQL2)
If yes it should update the data from table1.coloumn2 (varchar2) to table2.coloumn4 (varchar2).
If I understand correctly, you want to update table1.column2 to the corresponding value in table2.column1 based on other conditions. Based on your description:
update table1
column2 = (select column4 from table2 t2 where t2.column1 = table1.column6)
where exists (select 1 from table2 t2 where t2.column1 = table1.column6);
MERGE is good for updating/inserting tables based on other tables. Something like this should work (would be a bit more clear with distinctly-named columns). It also accepts an optional 'WHEN NOT MATCHED THEN' clause which lets you insert new records.
MERGE INTO table2
USING (SELECT column2, column6 FROM table1) table1
ON (table2.column1 = table1.column6)
WHEN MATCHED THEN
update set column4 = column2;

Insert a Row with values from multiple tables (SQL Server)

I'm defining a delete trigger, and I need to backup the row deleted but only a few arguments from the original and including one column from other table:
TableC:
* Column 1: value from a column in TableA
* Column 2 to 6: values from colums 1,2,3,5,6 from TableB
All I want is something like this:
INSERT into TableC values (
(SELECT Column1A from TableA where TableA.Column = 'SomeValue'),
(SELECT column1, column2, column3, column5, column6 from TableB));
The result on TableC must be:
Column1A , column1, column2, column3, column5, column6
But that is not working.
In my special case, TableB is the deleted table accessible only in triggers.
I'm using SQL-Server 2008 but all I need is the logic of the query, and then I try to translate it.
Thank you.
In another case, which I honestly find very odd, that might be closer to what you're describing, this might work:
INSERT INTO MyTable
SELECT
(SELECT ColumnA FROM Table1),
Table2.ColumnA,
Table2.ColumnB,
Table2.ColumnC,
Table2.ColumnD
FROM
Table2
That way, you're only selecting that one column from Table1, yet selecting many columns from Table2, regardless of any relationship between them.
You need to do joins on the select.
Here's an example:
INSERT INTO MyTable
SELECT
Table1.ColumnA,
Table1.ColumnB,
Table2.ColumnA,
Table2.ColumnB
FROM
Table1
INNER JOIN Table2 ON Table1.ID = Table2.ID
This is just an example of "inserting from two tables".
You need to modify it to match what you're looking for, which I did not comprehend from your arbitrary example.
You can use a cross join to join unrelated tables:
INSERT MyTable
(col5, col7)
SELECT t1.col5
, t2.col7
FROM Table1 t1
CROSS JOIN
Table2 t2
WHERE t1.ID = 'SomeValue'
and t2.ID = 'OtherValue'
If one of the tables just contains one row, you can omit the where part for it.

SQL Query Help

Duplicate:
How to do a Select in a Select
I have 2 tables:
TABLE1
Table1Id
TABLE2
Table2Id
Table1Id
UserId
TABLE2 has thousands of entries in it. I want to return a list of TABLE1 entries where there isn't an entry in TABLE2 for it for a particular user. So, where there isn't a foreign key entry in TABLE2. A query like:
select count(*) from TABLE1 where Table1Id not in (
select Table1Id from TABLE2 where id_user = 1)
However, that query runs very slowly. What would be the most efficient way of getting the results I require?
There is a similar question
I think it would be better
SELECT COUNT(*)
FROM TABLE1
WHERE NOT EXISTS (SELECT Table1Id FROM TABLE2 WHERE TABLE2.Table1Id = TABLE1.Table1Id AND UserID = 1)
I would check the indexes also, as ck suggested
What about
select Table1Id from TABLE1
minus
select Table1Id from TABLE2 where id_user = 1
I am not sure, it MsSql support minus. If not, you should try a correlated subquery.
You can also use the 'EXCEPT/MINUS' intersect to get only differences between the two tables as long as the selection returns the same field types/order.
SELECT TABLE1ID
FROM TABLE1
EXCEPT -- or MINUS in Oracle
SELECT TABLE1ID
FROM TABLE2
WHERE USER_ID = 1
See How to do a Select in a Select
Also, make sure that any fields you are querying have a suitable index.