SQL Select Into Field - sql

I want to accomplish something of the following:
Select DISTINCT(tableA.column) INTO tableB.column FROM tableA
The goal would be to select a distinct data set and then insert that data into a specific column of a new table.

SELECT column INTO tableB FROM tableA
SELECT INTO will create a table as it inserts new records into it. If that is not what you want (if tableB already exists), then you will need to do something like this:
INSERT INTO tableB (
column
)
SELECT DISTINCT
column
FROM tableA
Remember that if tableb has more columns that just the one, you will need to list the columns you will be inserted into (like I have done in my example).

You're pretty much there.
SELECT DISTINCT column INTO tableB FROM tableA
It's going to insert into whatever column(s) are specified in the select list, so you would need to alias your select values if you need to insert into columns of tableB that aren't in tableA.
SELECT INTO

Try the following...
INSERT INTO tableB (column)
Select DISTINCT(tableA.column)
FROM tableA

The goal would be to select a distinct data set and then insert that data into a specific column of a new table.
I don't know what the schema of tableB is... if table B already exists and there is no unique constraint on the column you can do as any of the others suggest here....
INSERT INTO tableB (column)Select DISTINCT(tableA.column)FROM tableA
but if you have a unique constraint on table B and it already exists you'll have to exclude those values already in table B...
INSERT INTO tableB (column)
Select DISTINCT(tableA.column)
FROM tableA
WHERE tableA.column NOT IN (SELECT /* NOTE */ tableB.column FROM tableB)
-- NOTE: Remember if there is a unique constraint you don't need the more
-- costly form of a "SELECT DISTICT" in this subquery against tableB
-- This could be done in a number of different ways - this is just
-- one version. Best version will depend on size of data in each table,
-- indexes available, etc. Always prototype different ways and measure perf.

Related

Insert new/Changes from one table to another in Oracle SQL

I have two tables with same number of columns :-Table A and Table B
Every day I insert data from Table B to Table A. now the insert query is working
insert into table_a (select * from table_b);
But by this insert the same data which was inserted earlier that is also getting inserted. I only want those rows which are new or are changed from the old data. How can this be done ?
You can use minus:
insert into table_a
select *
from table_b
minus
select *
from table_a;
This assumes that by "duplicate" you mean that all the columns are duplicated.
If you have a timestamp field, you could use it to limit the records to those created after the last copy.
Another option is, assuming that you have an primary key (id column in my example) that you can use to know whether a record has already been copied, you can create a table c (with the same structure as a and b) and do the following:
insert into table c
select a.* from table a
left join table b on (a.id=b.id)
where b.id is null;
insert into table b select * from table c;
truncate table c;
You need to adjust this query in order to use the actual primary key.
Hope this helps!
If the tables have a primary or unique key, then you could leverage that in an anti-join:
insert into table_a
select *
from table_b b
where not exists (
select null
from table_a a
where
a.pk_field_1 = b.pk_field_1 and
a.pk_field_2 = b.pk_field_2
)
You don't say what your key is. Assuming you have a key ID, that is you only want ID's that are not already in Table A. You can also use Merge-Statement for this:
MERGE INTO A USING B ON (A.ID = B.ID)
WHEN NOT MATCHED THEN INSERT (... columns of A) VALUES (... columns of B)

t-sql defect when selecting an non-existent column from a temp table [duplicate]

I have a piece of SQL which (you would think) wouldn't compile, but which instead deletes all rows from the target table.
Consider this setup:
create table TableA (ColumnA varchar(200));
create table TableB (ColumnB varchar(200));
insert TableA values ('A'),('B'),('C');
insert TableB values ('A');
Then the following sql:
--Returns all rows from TableA
select * from TableA;
--Does not error (ColumnA does not exist on TableB)
delete TableA where ColumnA in (select ColumnA from TableB)
--No Rows are returned
select * from TableA;
The delete statement above causes all rows to be removed from TableA, rather than erroring that ColumnA doesn't exist in TableB
There's a SQL Fiddle demontrating this here: http://www.sqlfiddle.com/#!3/9d883/6
It seems that the ColumnA from TableA is being picked up, but expected it to be "out of scope".
Why is this?
That works as expected, due to the correlation between ColumnA in the inner query to the outer.
This commonly used correlated query pattern is valid
DELETE TableA WHERE NOT EXISTS (select * from TableB where TableB.ID=TableA.ID)
It removes TableA entries that don't have a dependent record in TableB.
It shows that you can reference TableA columns in a correlated query. In your query
delete TableA where ColumnA in (select ColumnA from TableB)
The inner query is producing
one row for each record in TableB
one column for each row, whose value is ColumnA from outer query
So the DELETE goes through
While I understand the confusion, it is behaving as it should. ColumnA is still "in scope". In fact you could join on it in your subquery if you wanted. The brackets don't limit the scope, but from a readability standpoint I can see the confusion that it creates.
This is another example of why it's a good idea to always prefix your column names with the table name (or alias).

How to loop through rows in two tables and create a new set based on the merged results in SQL

Here is my obstacle.
I have two tables. Table A contains more rows than Table B. I have to merge the results and if Table A does not contain a row from Table B then I insert it into the new set. If however, a row from Table A contains a row with the same primary key as Table B, the new set will take the row from Table B.
Would this best be done in a cursor or is there an easier way to do this? I ask because there are 20 million rows and while I am new to sql, i've heard cursors are expensive.
Your phrasing is a little vague. It seems that you want everything from TableB and then rows from TableA that have no matching primary key in B. The following query solves this problem:
select *
from tableB union all
select *
from tableA
where tableA.pk not in (select pk from tableB)
Yep, cursors are expensive.
There's a MERGE command in later versions of SQL that will do this in one shot, but it's sooo cumbersome. Better to do it in two pieces - first:
UPDATE A SET
field1 = B.field1
,field2 = B.field2
, etc
FROM A JOIN B on B.id = A.id
Then:
INSERT A SELECT * FROM B --enumerate fields if different
WHERE B.id not in (select id FROM A)
An OUTER JOIN should do what you need and be more efficient than a cursor.
Try this query
--first get the rows that match between TableA and TableB
INSERT INTO [new set]
SELECT TableB.* --or columns of your choice
FROM TableA LEFT JOIN TableB ON [matching key criteria]
WHERE TableB.[joining column/PK] IS NOT NULL
--then get the rows from TableA that don't have a match
INSERT INTO [new set]
SELECT TableA.* --you didn't say what was inserted if there was no matching row
FROM TableA LEFT JOIN TableB ON [matching key criteria]
WHERE TableB.[joining column/PK] IS NULL

Compare unique values from two mysql tables

I have two mysql tables: TableA has 10,000 records TableB has 2,000 records.
I want to copy the 8,000 unique records from TableA into TableB ignoring the 2,000 in TableB which have already been copied.
If uniqueness is determined by PRIMARY KEY constraint or UNIQUE constraint, then you can use INSERT IGNORE:
INSERT IGNORE INTO TableB SELECT * FROM TableA;
The rows that are duplicates and that conflict with rows already in TableB will be silently skipped and the other 8,000 rows should be inserted.
See the docs on INSERT for more details.
If you need to do this in PHP, read about the array_diff_key() function. Store your arrays with the primary key values as the key of the array elements. No guarantees for the performance of this PHP function on such large arrays, though!
Use the INSERT INTO syntax:
INSERT INTO TABLE_B
SELECT *
FROM TABLE_A a
WHERE NOT EXISTS(SELECT NULL
FROM TABLE_B b
WHERE b.column = a.column)
You'll need to update the WHERE b.column = a.column) to satisfy however you determine that a record already exists in TABLE_B.
What about something like this :
insert into TableB
select *
from Table A
where not exists (
select 1
from TableB
where TableB.id = TableA.id
)
Or, if the entries in table B are "not unique" because of their primary key, an insert ignore might do the trick, I suppose.

MySQL how to remove records in a table that are in another table

I have table A with close to 15000 entries. I have a second table B with 7900 entries with a common field with table A.
I need to extract into a third temporary tableC all entries from table A except the ones that also appear in table B. Simple as it may sound, i havent found a way to do it. The closest i got was this:
INSERT INTO tableC
SELECT *
FROM tableA
INNER JOIN tableB
ON tableA.field IS NOT tableB.field
This SQL just selects everything in tableA, even entries that are in tableB.
Any ideas where i'm going wrong?
What if you try this?
INSERT INTO tableC
SELECT *
FROM tableA
WHERE tableA.field NOT IN (SELECT tableB.field FROM tableB)
Or you can try the alternate EXISTS syntax
INSERT INTO tableC
SELECT *
FROM tableA
WHERE NOT EXISTS (SELECT * FROM tableB WHERE tableB.field = tableA.field)