From doing a bit of research it seems it’s not possible to do an insert with a where clause?
I have a table I want to import into another table where specific record criteria doesn’t already exist. How would I go about this ?
E.g pseudo code -
insert into table b (select * from table a) where not exists tableb.column1 = tablea.column1 and tableb.column2 = tablea.column2
Could this potentially be done with a Join ?
You can insert using INSERT INTO.. SELECT with NOT EXISTS.
Query
insert into [TableB]
select * from [TableA] as [t1] -- [TableA] and [TableB] structure should be same.
where not exists(
select 1 from [TableB] as [t2]
where [t1].[column1] = [t2].[column1]
and [t1].[column2] = [t2].[column2]
);
Or, if the table structure is not same and need to same few columns, then
Query
insert into [TableB]([column1], [column2], ..., [columnN])
select [column1], [column2], ..., [columnN]
from [TableA] as [t1]
where not exists(
select 1 from [TableB] as [t2]
where [t1].[column1] = [t2].[column1]
and [t1].[column2] = [t2].[column2]
);
You can also use LEFT JOIN with IS NULL as below:
INSERT INTO tableb
SELECT a.*
FROM tablea a
LEFT JOIN tableb b ON b.column1 = a.column1
AND b.column2 = a.column2
WHERE b.column1 IS NULL
Referencing table name from INSERT statement in SELECT part will not work, because INSERT is not a query itself, but nothing prevents to query destination table in SELECT, which produces the data set to be inserted.
INSERT INTO tableb (column1, column2)
SELECT column1, column2 FROM tablea
WHERE NOT EXISTS (SELECT * FROM tableb
WHERE tableb.column1 = tablea.column1
AND tabled.column2 = tablea.column2)
Try this :
Via Insert with Select statement with Not Exists
Declare #table1 table(Id int , EmpName varchar(100) )
Declare #table2 table(Id int , EmpName varchar(100) )
Insert into #table1 values (1,'Ajay'), (2, 'Tarak') , (3,'Nirav')
Insert into #table2 values (1,'Ajay')
--Insert into table b (select * from table a) where not exists tableb.column1 = tablea.column1 and tabled.column2 = tablea.column2
INSERT INTO #table2 (id, empname)
select id, empname from #table1
EXCEPT
SELECT id, empname from #table2
Select * from #table1
Select * from #table2
Via merge
Insert into #table2 values (4,'Prakash')
Select * from #table1
Select * from #table2
Declare #Id int , #EmpName varchar(100)
;with data as (select #id as id, #empname as empname from #table1)
merge #table2 t
using data s
on s.id = t.id
and s.empname = t.empname
when not matched by target
then insert (id, empname) values (s.id, s.empname);
Select * from #table1
Select * from #table2
Related
I need to convert scripts for SQL Server, so I can use them for SQLite.
The scripts look like this:
DECLARE #var1 int = (SELECT Id FROM Table1 WHERE id = 'val1')
DECLARE #var2 int = (SELECT Id FROM Table2 WHERE id = 'val2')
IF NOT EXISTS(SELECT * FROM Table3 WHERE id_1 = #var1 and id_2 = #var2)
INSERT INTO Table3(id_1, id_2) VALUES (#var1, #var2)
GO
IF NOT EXISTS(SELECT * FROM Table4 WHERE id ='val3')
INSERT INTO Table4(id, desc) values ('111', 'new entry')
GO
What is the best practice for executing these scripts in SQLite?
SQLite does not support variables.
You can use a CTE that returns the values of the 2 variables as columns:
WITH cte(var1, var2) AS (
SELECT (SELECT Id FROM Table1 WHERE id = 'val1'), (SELECT Id FROM Table2 WHERE id = 'val2')
)
INSERT INTO Table3(id_1, id_2)
SELECT var1, var2
FROM cte
WHERE NOT EXISTS (SELECT * FROM Table3 t3 INNER JOIN cte c ON t3.id_1 = c.var1 AND t3.id_2 = c.var2);
INSERT INTO Table4(id, `desc`)
SELECT '111', 'new entry'
WHERE NOT EXISTS (SELECT * FROM Table4 WHERE id ='val3')
I am trying to do the following:
Set the status column to 1 when the row in the first table (variable) does not exist in the second one.
I tried this:
update #table1
set status=1
where NOT EXISTS (select top 1 1 from #table2 where #table1.foo=#table2.foo)
But this doesn't even compile, not recognizing #table1 in the Where statement.
Must declare the scalar variable "#table1".
Any clue about this?
Your approach is fine. You just need table aliases because the # is used to in SQL Server to represent variables (scalars or tables) and is hence problematic for aliases:
update t1
set status = 1
from #table1 t1
where not exists (select 1 from #table2 t2 where t2.foo = t1.foo);
Note that the top 1 is unnecessary in the subquery.
You can do this kind of thing by joining the two tables with a LEFT JOIN and checking the right side for NULL:
UPDATE t1
SET t1.status=1
FROM #table1 t1
LEFT JOIN #table2 t2
ON t1.foo = t2.foo
WHERE t2.foo IS NULL
The specific error you got is because you haven't got a statement declaring #table1 as a table variable, like DECLARE #table1 TABLE (foo int) for example. If table1 is not a variable, you don't need the #.
no need any top inside scaler query
update #table1
set status=1
where NOT EXISTS (select 1 from #table2 where #table1.foo=#table2.foo)
cause exists return boolean
you could use below query
update #table1
set status=1
where #table1.foo not in ( select foo from #table2 where foo is not null)
There are multiple ways - inner query with NOT IN and NOT EXISTS and JOIN query:
update tab1 set status = 1 where name not in (select name from tab2);
update tab1 set status = 1 where not exists (select 1 from tab2 where tab1.name=tab2.name);
update tab1 set status = 1 from tab1 left outer join tab2 on tab1.name = tab2.name where tab2.name is null;
Sample schema to run above queries;
create table tab1(name varchar(30), status int);
create table tab2(name varchar(30));
insert into tab1 values('a', 5);
insert into tab1 values('b', 6);
insert into tab1 values('c', 7);
insert into tab1 values('d', 8);
insert into tab2 values('a');
insert into tab2 values('d');
You have to declare table1 and table2 variables
DECLARE #table1 YOUR_TABLE1_NAME;
DECLARE #table2 YOUR_TABLE2_NAME;
update #table1
set status=1
where NOT EXISTS (select top 1 from #table2 where #table1.foo=#table2.foo)
You should use alias name for both table.
DECLARE #TABLE_1 TABLE (DEPT_NAME VARCHAR(50),DEP_ID INT)
INSERT INTO #TABLE_1(DEPT_NAME,DEP_ID)
SELECT 'IT',1 UNION ALL
SELECT 'HR',2 UNION ALL
SELECT 'ACCOUNT',3 UNION ALL
SELECT 'ADMIN',4 UNION ALL
SELECT 'SALES',5 UNION ALL
SELECT 'CEO',7
DECLARE #TABLE_2 TABLE (E_ID INT,EMP_NAME VARCHAR(50),DEP_ID INT)
INSERT INTO #TABLE_2(E_ID,EMP_NAME,DEP_ID)
SELECT 1,'JHON',1 UNION ALL
SELECT 2,'LITA',2 UNION ALL
SELECT 3,'MATT',1 UNION ALL
SELECT 4,'JEFF',1 UNION ALL
SELECT 5,'BROCK',2 UNION ALL
SELECT 6,'BOB',5 UNION ALL
SELECT 7,'SAM',4 UNION ALL
SELECT 8,'DAVID',3 UNION ALL
SELECT 9,'JACK',1 UNION ALL
SELECT 10,'GARY',4 UNION ALL
SELECT 11,'DONALD',6
SELECT * FROM #TABLE_1 A WHERE NOT EXISTS (SELECT DEP_ID FROM #TABLE_2 B WHERE A.DEP_ID=B.DEP_ID )
I need to do something like this:
SET #MyTableAsArgument = 'Foo;Bar\n1;2\n3;4\n'; -- CSV or any other table-format
SET #AnOtherArgument = 'somedata';
SELECT * FROM table1 t1, #MyTableAsArgument t2
WHERE t1.foo = t2.foo
AND t1.bar = #AnOtherArgument
Is there a way to do this?
The only other solution I see is:
Create a temporary table tmp1
Insert my MyTableAsArgument to the tmp1
Do My query on table1 and tmp1
Delete my temporary table tmp1
I am not sure if this is an abuse of temporary tables.
Is there a significant performance overhead with temporary tables as they are used for queries?
Can you use a table variable or temporary table?
DECLARE #MyTable TABLE (foo VARCHAR(255));
INSERT INTO #MyTable (foo)
VALUES ('Foo'), ('Bar\n12\n3'), ('4\n');
SET #AnOtherArgument = 'somedata';
SELECT t1.*
FROM table1 t1
WHERE t1.foo IN (SELECT foo FROM #MyTable) AND
t1.bar = #AnOtherArgument;
If this is not possible, you can use a SPLIT() functions -- STRING_SPLIT() is built into the most recent versions -- but other versions are on the web:
SELECT *
FROM table1 t1
WHERE t1.foo IN (SELECT foo FROM string_split(#MyTableLIST, ';') ss(foo)) AND
t1.bar = #AnOtherArgument;
#Cosinus, there is a temp table variable too in SQL. This allows you to define the columns you want in that table and using a 'union all' you can insert elements in that table.
See this mockup below.
DECLARE #MyTableAsArgument table(Name varchar(20), foo varchar(50), descb varchar(100), pj_id int)
DECLARE #AnOtherArgument varchar(20) = 'somedata';
INSERT into #MyTableAsArgument
SELECT 'James', 'iphone', 'cell phone', 1 union all
SELECT 'Michael', 'macbook', 'laptop', 2 union all
SELECT 'Henry', 'windows', 'os', 3
SELECT *
FROM
table1 t1
Join #MyTableAsArgument t2 ON
t1.foo = t2.foo
AND
t1.bar = #AnOtherArgument
I am working in SQL Server 2008. I have 2 tables Table1 & Table2.
Table1 has columns
SchoolCode, District, Type, SchoolName
and Table2 has columns
SchoolCode1, District1, Type1, SchoolName1
SchoolCode columns in both tables have the same codes like "1234"; code is the same in both schoolcode columns.
Now I want to copy the District, Type and SchoolName column values from Table1 to Table2 if SchoolCode in both tables is same.
I think the query will use join but I don't know how it works. Any help on how I can do this task?
Maybe use an update statement in join if by copying over you mean updating rows
update t2
set
District1= District,
Type1= Type,
SchoolName1= SchoolName
from Table1 t1
join
Table2 t2
on t1.SchoolCode=t2.SchoolCode1
I could give you a little bit of idea. here is it:
Insert into table2 (District1, Type1, SchoolName1)
SELECT District, Type, SchoolName
FROM table1
where table1.Schoolcode=table2.Schoolcode1
You have to use Inner join to update data from table 1 to table 2, Inner join will join values that are equal. . To learn more about joins, I highly recommend you to read the below article
SQLServer Joins Explained - W3Schools
Please refer the below code, for the convenience I have used the temporary tables..
DECLARE #Table1 TABLE
(
SchoolCode INT,
District VARCHAR(MAX),
Type VARCHAR(MAX),
SchoolName VARCHAR(MAX)
)
DECLARE #Table2 TABLE
(
SchoolCode1 INT,
District1 VARCHAR(MAX),
Type1 VARCHAR(MAX),
SchoolName1 VARCHAR(MAX)
)
INSERT INTO #Table1
( SchoolCode ,District , Type , SchoolName
)
VALUES ( 1 ,'DIS1' ,'X' ,'A'),
( 2 ,'DIS2' ,'Y' ,'B'),
( 3 ,'DIS3' ,'Z' ,'C'),
( 4 ,'DIS4' ,'D' ,'D'),
( 5 ,'DIS5' ,'K' ,'E')
INSERT INTO #Table2
( SchoolCode1 ,District1 , Type1 , SchoolName1
)
VALUES ( 1 ,'DIS1' ,'X' ,'A'),
( 2 ,NULL ,'Z' ,NULL),
( 3 ,'DIS3' ,'Z' ,'C'),
( 4 ,NULL ,'Z' ,'S'),
( 5 ,'DIS5' ,'K' ,'E')
--BEFORE
SELECT * FROM #Table1
SELECT * FROM #Table2
--Logic UPDATE Table 2
UPDATE t2 SET t2.District1 = t1.District,
t2.Type1 = t1.Type,
t2.SchoolName1 = t1.SchoolName
FROM #Table1 t1
INNER JOIN #Table2 t2 ON t1.SchoolCode = t2.SchoolCode1
-- End Logic UPDATE Table 2
--AFTER
SELECT * FROM #Table1
SELECT * FROM #Table2
You can join tables in an UPDATE statement.
Note, I have aliased the tables, table1 and table2 as t1 and t2 respectively.
This is what I did:
create table Table1
(SchoolCode varchar(50),
District varchar(50),[Type] varchar(50),SchoolName varchar(50))
go
create table Table2
(SchoolCode1 varchar(50), District1 varchar(50),[Type1] varchar(50),SchoolName1 varchar(50))
go
insert into table1 values ('1234','District1','High','Cool School')
insert into table1 values ('2222','District2','Lower','Leafy School')
insert into table2 (SchoolCode1) values ('1234')
go
update t2
set District1 = District,
Type1 = [Type],
SchoolName1 = SchoolName
from table1 t1
join table2 t2
on t2.SchoolCode1 = t1.SchoolCode
go
select * from table2
go
Here is the scenario. I have two tables. I want to merge multiple row value to single value using update query.
DECLARE #Table as Table
(
id int,
name varchar(10)
)
insert into #Table values(1,'a')
insert into #Table values(1,'b')
insert into #Table values(1,'c')
select * from #Table
DECLARE #Table2 as Table
(
id int,
name varchar(10)
)
insert into #Table2 values(1,'a')
update t2 set name = t1.name from #Table2 t2
inner join #Table t1 on t1.id=t2.id
select * from #Table2
I want output from #Table2 as by using update query
id name
----- --------
1 a,b,c
;WITH Table1 AS (
SELECT t.id
, STUFF((SELECT ',' + name
FROM #Table
WHERE id = t.id
FOR XML PATH(''), TYPE)
.value('.','NVARCHAR(MAX)'),1,1,'') AS name
FROM #Table t
GROUP BY t.id)
UPDATE t2
SET t2.name = t1.name
FROM #Table2 t2
INNER JOIN Table1 t1 ON t1.id=t2.id