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

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.

Related

How to copy an sql column based on foreign key?

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);

SQL - Comparing two tables with Minus - Include/Exclude temp field

After carefully reading a lot of topics about comparing tables and using the minus function I'm posting this.
I've got my comparison between two tables running.
Select Column1,Column2.. from table 1
minus Column1,Column2.. from table 2
union all
Column1,Column2.. from table 2
Select Column1,Column2.. from table 1
order by column1
Now this gives me a list of duplicate or single values that are different in each table. This is fine. However I do not have an indicator telling me in which table the (faulty) rows are.
I tried adding a temporary column giving it an A and B field. This results in a full export of the table because this obviously gets taken in with the minus function.
Is there a way that I can tag the rows telling me what table they are in without adding a permanent column in the table,because this is not an option.
Help is much appreciated!
I would phrase this as a union of left joins:
SELECT t1.col1, t1.col2, 'table1' AS label
FROM table1 t1
LEFT JOIN table2 t2
ON t1.col1 = t2.col1 AND t1.col2 = t2.col2
WHERE t2.col1 IS NULL
UNION ALL
SELECT t2.col1, t2.col2, 'table2'
FROM table2 t2
LEFT JOIN table1 t1
ON t1.col1 = t2.col1 AND t1.col2 = t2.col2
WHERE t1.col1 IS NULL
The label column is computed during the UNION and serves to label the origin table for each record (i.e. set of values) which are unique to that particular table. Note that you can extend what I have given above by adding the necessary number of columns to fill both tables.
This is a general solution which should work across most RDBMS, and doesn't rely on any set difference operators.
Demo here:
SQLFiddle
The example query you provided isn't syntactically correct and has errors when running. But, based on the description of what you tried, I think I understand what you're trying to accomplish.
You were on the right track with adding a temporary column that provides an indicator of which table is the source of the row. The value of the temporary column should be the same for the queries before the UNION ALL and a different value for the queries after.
Here's an updated version of your example query. You can try it out at SqlFiddle
(
SELECT 'FromTable1', COLUMN1, COLUMN2, COLUMN3 FROM TABLE1
EXCEPT
SELECT 'FromTable1', COLUMN1, COLUMN2, COLUMN3 FROM TABLE2
)
UNION ALL
(
SELECT 'FromTable2', COLUMN1, COLUMN2, COLUMN3 FROM TABLE2
EXCEPT
SELECT 'FromTable2', COLUMN1, COLUMN2, COLUMN3 FROM TABLE1
)

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;

using sql create a new table with 2 fields, field1 from tableA and field1 from table B

Am new to SQL and am stuck here with a very simple-looking query request.
I have 2 tables, both having exactly the same structure (IE same no. of columns, same no. Of rows) except for the actual contents. so for example,tableA has 2 columns called col1&col2; tableB has 2 columns too called col1&col2. Now I want to create a 3rd new tale, where 1st column is tableA's col1, and 2nd column is tableB's col1. preferably the name of the 1st column is fromTableA, and name of 2nd column is fromTableC. How do I achieve this please? I tried all the following ways but I always get the same error: "number of query values and destination fields are not the same."
variation 1:
insert into newTable(fromTable1,fromTable2)
select col1 from table1
select col1 from table2
variation 2:
insert into newTable(fromTable1,fromTable2)
select col1 from table1,col1 from table2
variation 3:
insert into newTable(fromTable1,fromTable2)
select col1 from table1, table2
Presumably you have fields in the two tables that can be joined, so this:
insert into newtable (romTable1,fromTable2)
select a.col1, b.col1
from table1 a, table2 b
where a.col1 = b.col1;
The a/b are aliases that differentiate between the two columns in each table. If you don't have fields to join then whatever you're trying to do probably needs a rethink.
You may try following sql query to achieve your purpose:
with OrderedTableA as (
select row_number() over (order by Col1) RowNum, *
from TableA (nolock)
),
OrderedTableB as (
select row_number() over (order by Col1) RowNum, *
from TableB (nolock)
)
select T1.Col1, T2.Col2 into TableC
from OrderedTableA T1
full outer join OrderedTableB T2 on T1.RowNum = T2.RowNum
Above query will create a new table as TableC with column col1 from TableA and col2 from TableB. You may change the queries to your need.
I hope you will understand the above queries. Give it a try.

Inserting new records can cause timeout if someone queries this table?

I'm using Microsoft SQL Database
I have a table with about 1000000 records. Each day I update it with new ones.
so I have two tables
Table1 where all records
and
Table2 where new records. The idea is to insert only the new ones. Because Table1 can contain already some of the records from Table2. Usually about 600K
Here is the query I'm using to update table with the new records.
INSERT INTO Table1
(
Column1, Column2, Column3
)
SELECT Column1, Column2, Column3
FROM Table2
LEFT OUTER JOIN Table1
ON Table1.ColumnID = Table2.ColumnID
WHERE Table1.ColumnStockID IS NULL
The issue I have during the time executing this query. Most of the queries to table 1, which select more than 1-10 records are giving time out. Even on the server I don't see high CPU.
Is the a problem in my query? Is there any way to make it more efficient?
Or other more efficient way to insert new records?
Also the same happens when I'm trying to delete
DELETE ITEMS
FROM Table1 ITEMS WITH(NOLOCK)
LEFT OUTER JOIN Table2 NEWITEMS
ON ITEMS.ID = NEWITEMS.ID
WHERE NEWITEMS.ID IS NULL AND ITEMS.ID IS NOT NULL
Try to insert the records in local temporary table and then insert it from local temporary table select statement.
SELECT Column1, Column2, Column3
into #temp FROM Table2
LEFT OUTER JOIN Table1
ON Table1.ColumnID = Table2.ColumnID
WHERE Table1.ColumnStockID IS NULL
INSERT INTO Table1
(
Column1, Column2, Column3
)
Select * from #temp
Drop table #temp
First what are your indexes? FKs do not automatically get indexed.
NOT EXISTS is usually a faster form than the left join form to find records in one table but not the other.
INSERT INTO Table1 (Column1, Column2, Column3)
SELECT Column1, Column2, Column3
FROM Table2 t2
WHERE NOT EXISTS (SELECT *
FROM Table1 t1
WHERE t1.ColumnId = t2.ColumnId)
The join to table 1 is probably locking rows. In a table this big, with a large number of joins, SqlServer will quickly escalate the row locks to page locks to table locks.
Try adding "with (nolock) after the select/join from table1. This might keep the locks from blocking other queries.
You need to see if adding (nolock) is right for your situation. It should not be applied without understanding the downsides. It is not a cure all.
Why do you need to join Table1 and Table2? I don't think this is required. Joining takes a significant amount of time and hence the timeouts.
If you are using MySql, INSERT IGNORE would take care of unique inserts and you need not join Table1 and Table2.