SQL server 2000 insert rows when join does not match - sql-server

I would simply like to insert rows from a table to another if rows does not exist in the target.
How should I code that? with inner join?
Below is the query which returns rows that match between source and target
select * from LOG_S1201_REFERENCE_T1 b
inner join LOG_S1201_REFERENCE_STAGING_WT5 a on b.OU_ID=a.OU_ID and
b.Plant_desc=a.Plant_desc and b.workshop=a.workshop and
b.SerieNum=a.SerieNum and b.Operation_type=a.Operation_type and
b.PC10DBName=a.PC10DBName and b.SimuDBName=a.SimuDBName and
b.ProgramName=a.ProgramName and b.Calibre=a.Calibre

Copying rows can be done through INSERT SELECT
Need an example?
INSERT INTO new_table (col1, col2, col3)
SELECT col4, col5, col6
FROM old_table
HAVING !(SELECT COUNT(*) FROM new_table WHERE col1 = old_table.col4)

Join the table that has all rows with left join with the table that has some of the rows.
Filter one of the left joined table column with IS NULL
INSERT INTO your_table
select b.*
from LOG_S1201_REFERENCE_T1 b
left join LOG_S1201_REFERENCE_STAGING_WT5 a on b.OU_ID=a.OU_ID and b.Plant_desc=a.Plant_desc and b.workshop=a.workshop and b.SerieNum=a.SerieNum and b.Operation_type=a.Operation_type and b.PC10DBName=a.PC10DBName and b.SimuDBName=a.SimuDBName and b.ProgramName=a.ProgramName and b.Calibre=a.Calibre
WHERE a.OU_ID IS NULL

In order to select rows that do NOT match you need to do a left join.
INSERT INTO LOG_S1201_REFERENCE_T1 b2
SELECT a.* FROM LOG_S1201_REFERENCE_STAGING_WT5 a
LEFT JOIN LOG_S1201_REFERENCE_T1 b ON
(b.OU_ID=a.OU_ID
AND b.Plant_desc=a.Plant_desc
AND b.workshop=a.workshop
AND b.SerieNum=a.SerieNum
AND b.Operation_type=a.Operation_type
AND b.PC10DBName=a.PC10DBName
AND b.SimuDBName=a.SimuDBName
AND b.ProgramName=a.ProgramName
AND b.Calibre=a.Calibre)
WHERE b.OU_ID IS NULL
This will select all rows from a that are not in b which will then be inserted into a.
Afterwards a and b should be identical (except for b rows that are not in a).

Related

Update grouped rows with ID of newly inserted grouping row

I want to group several rows of table A and insert a new row into table B for each bunch of grouped rows.
Next to that I want to update the rows of table A with the ID of the newly inserted row.
Inserting the lines into the table with 'grouplines' is like:
INSERT INTO B(...,...,...)
SELECT col1, col2 FROM A
GROUP BY col1,col2
This will produce a list of IDs in table B. I want to update the rows of table A with the ID of the corresponding group-row of table B.
Is there a possibilty to do this?
Some sample data:
After grouping table B looks like:
And then table A should look like:
As it is, your query potentially inserts more than one row.
I think that one solution would to use two queries: first insert in table b from table a, the update table a with newly created id(s) from table b.
INSERT INTO B(col1, col2, col3)
SELECT DISTINCT col1, col2, col3 FROM A
UPDATE A
SET A.B_ID = B.B_ID
FROM A
INNER JOIN B
ON A.col1 = B.col1
AND A.col2 = B.col2
AND A.col3 = B.col3
Deme on db<>fiddle
You can achieve table B by using Row_Number like below
Select ROW_NUMBER() OVER(ORDER BY Category) as ID, Name, Category
into #B
from #A
group by Name, Category
Then Update the table A after joining with table B like
Update a
set a.ID_Of_Group_row = b.ID
from #A a
inner join #B b on a.Category = b.Category
Output

TSQL: INSERT or UPDATE from SELECT result

I have the following query where I grab some data from tables, and use the result to insert into a table called finalTable. finalTable.col1 is a pk. However, there are some rows in the finalTable that already exists with the same pk prior to running the below query. I want to change it so that it inserts(if the pk does not exist in finalTable) or updates(if the pk already exist in finalTable).
INSERT INTO finalTable (col1, col2, col3, col4, col5)
(
SELECT o.id, 14, 0, 1, 4
FROM Table1 c
INNER JOIN Table2 m ON c.ID = m.ID
INNER JOIN Table3 o ON m.ID = o.ID
WHERE c.ID = 40
)
One solution I came up with is deleting any relevant rows in finalTable prior to running the above query.
Another solution I came up with is to use "if exists". I would put the select query in the if exists statement, the clause of the if, and the clause of the else. I don't like this solution as I have to put the select query in 3 places, rather than in just 1 place.
if exists(...)
begin
... -- update
end
else
begin
... -- insert
end
You can use MERGE statement for such cases.
MERGE finaltable as target
USING (SELECT o.id
FROM Table1 c
INNER JOIN Table2 m ON c.ID = m.ID
INNER JOIN Table3 o ON m.ID = o.ID
WHERE c.ID = 40) as source
ON target.col1=source.id
WHEN MATCHED THEN
UPDATE SET col2=14,col3=0,col4=1,col5=4
WHEN NOT MATCHED THEN
INSERT (col1, col2, col3, col4, col5)
VALUES (source.id,14, 0, 1, 4)

Finding all records that do NOT join on inner join of two tables?

I have a SQL Server query for an inner join...
SELECT *
FROM tableA
INNER JOIN tableB on tableA.my_id = tableB.my_id
How would I find all the records that did NOT match in this join?
You can use a FULL JOIN to combine the two tables, then use a WHERE clause to filter the results down to only non-matching rows by checking for a NULL in each tables primary key value.
Full outer join All rows in all joined tables are included, whether they are matched or not.
SELECT a.pk, b.pk
FROM tableA a
FULL JOIN tableB b ON a.pk=b.fk
WHERE
a.pk IS NULL
OR b.pk IS NULL
SELECT A2.* FROM TableA A2
WHERE A2.my_id NOT IN
(Select tableA.my_id FROM
tableA
inner join
tableB
on tableA.my_id = tableB.my_id)
you could similarly do the above starting SELECT B2.* FROM TableB B2, in order to separately query unmatched records in Table B
if you want all records in one table you could UNION ALL the two queries, depending on the table field structures being the same or how you specify the fields you select - what are you doing with the data?
SELECT * FROM tableA where my_id NOT IN (SELECT my_id from tableB)
UNION ALL
SELECT * FROM tableB where my_id NOT IN (SELECT my_id from tableA)

INSERT INTO a created table throws an error

The following code shows an error on the SELECT statement in line 2.
INSERT INTO (SELECT A.Column1, B.Column2
FROM Table1 A
LEFT JOIN Table2 B ON A.Id = B.Id) AB
SELECT Column1, Column2
FROM ExtraData C
What I'm trying to do here is - I have 2 tables, A and B, that need to be joined (to make the table AB) and then to this joined table I have to add a few extra rows which are present in C
If I create a temp table for the table AB before the INSERT INTO it seems to work fine.
Is there such a restriction on INSERT?
If you want to create a table called AB, using select into:
SELECT Column1, Column2
INTO AB
FROM ExtraData C;
It is not clear exactly what you are trying to do, though.
If that is the case, then use union all:
SELECT A.Column1, B.Column2
INTO AB
FROM Table1 A LEFT JOIN
Table2 B
ON A.Id = B.Id
UNION ALL
SELECT Column1, Column2
FROM ExtraData C;
If you already have the table defined, then do:
INSERT INTO AB(column1, column2)
SELECT A.Column1, B.Column2
FROM Table1 A LEFT JOIN
Table2 B
ON A.Id = B.Id
UNION ALL
SELECT Column1, Column2
FROM ExtraData C;
You cannot do that in SQL Server. I don't know what RDBMS supports this syntax, or even what you expect as output.
There are two ways to insert data into a temp table. You already discovered the first which is CREATE TABLE #AB (...) then INSERT INTO #AB.
The second way is to use SELECT ... INTO:
SELECT A.Column1, B.Column2
INTO #AB
FROM Table1 A
LEFT JOIN Table2 B
ON A.Id = B.Id
-- Now that #AB is defined, you can use INSERT INTO to add additional data
INSERT INTO #AB (Column1, Column2)
SELECT Column1, Column2
FROM ExtraData C
INSERT INTO SomeTable
SELECT A.Column1, B.Column2
FROM Table1 A
LEFT JOIN Table2 B
ON A.Id = B.Id
UNION
SELECT Column1, Column2
FROM ExtraData C

SQL Server SELECT statement

I need a query that returns rows from table A if value X in table A is not the same as the sum of value Y from corresponding row(s) in table B. The issue is that there may or may not be rows in table B that correspond to the rows in table A, but if there no rows in table B, then the rows from table A should still be returned (because there is not a matching value in table B.) So it is like a LEFT OUTER join scenario, but the extra complication of having a comparison as an additional selection criteria.
I have a query that does the opposite, ie. returns rows if the value in table A is the same as the value of row(s) in table B, but sadly this isn't what I need!
SELECT TableA.id, TableA.bdate
FROM TableA
LEFT JOIN TableB ON TableB.ID = TableA.id
WHERE TableA.select_field = 408214
AND TableA.planned_volume =
(select sum(actual_volume)
from
TableB
where TableB.id = TableA.id)
ORDER BY TableA.id
Any help greatly appreciated.
How about something like this:
SELECT TableA.Id, TableA.bdate
FROM TableA
LEFT JOIN
(
SELECT Id, SUM(actual_volume) AS b_volume
FROM TableB
GROUP BY Id
) AS TableBGrouping
ON TableBGrouping.Id= TableA.Id AND TableA.planned_volume <> b_volume
ORDER BY TableA.Id
WITH TotalVolumes
AS
(
SELECT id, SUM(actual_volume) AS total_volume
FROM TableB
GROUP
BY id
)
SELECT id, bdate, planned_volume
FROM TableA
EXCEPT
SELECT A.id, A.bdate, T.total_volume
FROM TableA AS A
JOIN TotalVolumes AS T
ON A.id = T.id;
SELECT TableA.id, TableA.bdate
FROM TableA
LEFT JOIN TableB ON TableB.ID = TableA.id
AND TableA.planned_volume <>
(select sum(actual_volume)
from
TableB
where TableB.id = TableA.id)
ORDER BY TableA.id

Resources