I want to insert values based on below code to a temporary table in postgresql
declare #output table (AuditScratchID bigint, AuditID bigint);
merge table atb
using (select
s.ID
....
....
....
from #temporaryTableVariable s
inner join ....
...............
..............
) as s
on 1 = 2 -- Impossible Condition so they never match
when not matched then
insert (.....)
values (.....)
output s.ID, inserted.ID
into #output;
Just to mention, how can I correlate values into temporary table
I don't understand the use of MERGE to begin with.
This seems like a straightforward insert ... select. To see the inserted rows, use the returning clause
insert into atb (...)
select ... columns ...
from some_table
join other_table on ...
returning *
Related
I need to update two tables with the same WHERE clause. The WHERE clause has hundreds of IDs so I want to avoid writing it twice like this...
UPDATE TABLE1
SET (values...)
WHERE ID in (list of IDs)
UPDATE TABLE2
SET (values...)
WHERE ID in (list of IDs) -- this is the same statement as above
Is there a way to merge these with one WHERE statement?
SQL Server does not support multi-table updates.
You can, however, put these ids in a table, that you can then use in your queries.
create table id_table (id int); -- or whathever datatype you need
insert into id_table (id) values (1), (2), ...; -- list of ids
Then:
update t
set ...
from table1 t
where exists (select 1 from id_table i where i.id = t.id)
You can't really do this in SQL Server. Your best bet is to create a temporary table:
select *
into toupdate
from values ( . . . ) v(id)
Then you can use this in the delete statements:
update table1
set . . .
where id in (select id from toupdate);
I'm trying to dynamically create a variable or table in SQL which will store distinct values as a result for another sql query.
declare sample_table table
( values varchar(100))
insert into #sample_table values (select t1.value from my_tablw as t1 group by t1.value);
Supposing the distinct values in column value can change from table query to another table query, I want to store the result of this query in a user defined variable/table which can be used later in another query.
Depending on your definition of can be used later you can use a local temp table or table variable.... you just need to change the syntax a bit to not use the values since you are inserting from the results of a query. I also used DISTINCT below which is clearer than the GROUP BY without an aggregate function.
declare sample_table table ([values] varchar(100))
insert into #sample_table
select distinct t1.value
from my_tablw as t1
--one way to use it
select *
from newTable
where columnVal in (select * from #sample_table)
--another way to use it
select at.*
from anotherTable at
inner join #sample_table t on
t.column = at.column
--and another way...
select f.*
from finalTable f
where exists (select * from #sample_table t where t.column = f.column)
If you need this to be used outside the scope of your current batch, you'll need to use a persisted table or global temporary table.
Out of accident I noticed that the following query is actually valid:
UPDATE bikes
SET price = NULL
FROM inserted
WHERE inserted.owner_id = 123456
This is part of a trigger where someone forgot to join the original table to the inserted table. The result is that when the trigger is executed, all prices are set to NULL.
The correct SQL statement is this:
UPDATE bikes
SET price = NULL
FROM inserted
INNER JOIN bikes ON bikes.id=inserted.id
WHERE inserted.owner_id = 123456
How/why is this first statement valid?
Why wouldn't it be valid? SQL Server doesn't know what you're trying to do. It thinks you want to update all of the fields where some condition exists on another table. See the last update below.
SETUP
declare #table table
(
id int,
name varchar(10)
)
declare #itable table
(
id int,
name varchar(10)
)
insert into #table (id, name)
select 1,'abc' union
select 2,'def' union
select 3,'ghi' union
select 4,'jkl' union
select 5,'mno' union
select 6,'pqr'
insert into #itable (id, name)
select 1,'abc' union
select 2,'def' union
select 3,'ghi' union
select 4,'jkl' union
select 5,'mno' union
select 6,'pqr'
All names on #table will change to zzz
update #table
set name = 'zzz'
from #itable i
where i.id = 1
select * from #itable
select * from #table
All names where id = 1 on #table becomes yyy
update #table
set name = 'yyy'
from #itable i
inner join #table t on i.id = t.id
where i.id = 1
select * from #itable
select * from #table
This will NOT update anything
update #table
set name = 'aaa'
from #itable i
where i.id = 133
select * from #itable
select * from #table
The first statement does not work as expected because it is missing the entire INNER JOIN line with the bikes and inserted table. Without that SQL Server will update all rows as all rows will qualify for an update when the inserted.owner_id = 123456.
You can reproduce this outside of the trigger in TSQL like :
update bikes set price =null
from SomeOtherTable
where SomeOtherTable.SomeColumn = 'some_value_that_exists'
This is syntactically valid statement in SQL Server. If the Intention is to update bikes table based on existance of a row in some unrelated table that cant be joined because the 2 tables arent related then this is how you would do it. But that is not your requirement. Hence why it updates all records instead of only those that match the bikes.id In programming terms this is called as a logical bug.
The inner join makes it more restrictive and forces to to update only those rows that match the join condition between the 2 tables (bikes.id=inserted.id comparison )
In Simple terms the from clause is optional..Consider below query..
update table
set id=10
This has one table right after update clause ,sql just updates it..
now consider below query..
update table1
set id=40
from table2..
What do you think SQL does,it updates all the rows same as first query..
unless you refer to another table in from clause and join like below
update t1
set t1.id=40
from
table1 t1
join
table2 t2
on t1.id=t2.id
below is the from clause explanation in update syntax stripped down to show only to relevant parts..
If the object being updated is the same as the object in the FROM clause and there is only one reference to the object in the FROM clause, an object alias may or may not be specified. If the object being updated appears more than one time in the FROM clause, one, and only one, reference to the object must not specify a table alias. All other references to the object in the FROM clause must include an object alias
As long as above rules are valid (as in your case),SQL will happily update table found immediately after update clause
If I have a sql statement like this:
select *
from tableA a
inner join tableB b on dbo.fn_something(a.ColX) = b.ColY
if you assume there are 5 rows in tableA with the same value for ColX will dbo.fn_something() be called with that value 5 times or just one time?
Clearly this is a trivial example, but I'm interested for the purposes of thinking about performance in a more complex scenario.
UPDATE
Thanks #DStanley, following from your answer I investigated further. Using SQL Profiler with the SP:StmtStarting event on the SQL below illustrates what happens. i.e. as you said: the function will be called once for each row in the join.
This has an extra join from the original question.
create table tableA
( id int )
create table tableB
( id_a int not null
, id_c int not null
)
create table tableC
( id int )
go
create function dbo.fn_something( #id int )
returns int
as
begin
return #id
end
go
-- add test data
-- 5 rows:
insert into tableA (id) values (1), (2), (3), (4), (5)
-- 5 rows:
insert into tableC (id) values (101), (102), (103), (104), (105)
-- 25 rows:
insert into tableB (id_a, id_c) select a.id, c.id from tableA a, tableC c
go
-- here dbo.fn_something() is called 25 times:
select *
from tableA a
inner join tableB b on a.id = b.id_a
inner join tableC c on c.id = dbo.fn_something(b.id_c)
-- here dbo.fn_something() is called just 5 times,
-- as the 'b.id_c < 102' happens to be applied first.
-- That's likely to depend on whether SQL thinks it's
-- faster to evaluate the '<' or the function.
select *
from tableA a
inner join tableB b on a.id = b.id_a
inner join tableC c on c.id = dbo.fn_something(b.id_c) and b.id_c < 102
go
drop table tableA ;
drop table tableB;
drop table tableC;
drop function dbo.fn_something;
go
It will be called for each row in a. I do not know of any optimization that would call the function just for unique inputs. If performance is an issue you could create a temp table with distinct input values and use thoce results in your join, but I would only do that it it was an issue - don't assume it's a problem and clutter your query unnecessarily.
If you declare your function as schema bound, it can be run one for each unique case. This requires that the function be deterministic and always has the same output for a given input.
CREATE FUNCTION dbo.fn_something (#id INT)
RETURNS INT
WITH SCHEMABINDING
AS
BEGIN
RETURN #id
END
GO
I need to insert values from two tables into one table. Eg Table 1 is outward and table 2 is product table. I need to insert values into outward table and from product table i have productname which needs to be inserted into outward table. My code is
INSERT INTO tbltrn_outward, tbltrn product(chalanno,godownsrno, igodownsrno,deladdress,outwarddate,productname,qty,boxes,rate,price,batchcombo,active,createdby,createdon,fyearsno)
VALUES('$chalanno','$godownsrno','$igodownsrno','$deladdress','$outwarddate','$productname','$qty','$boxes','$rate','$price','$batchcombo','$active','$createdby','$createdon','$fyearsrno')";
You should use insert into .. select from construct for this purpose like
INSERT INTO tbltrn_outward(col1,col2,col3, ...)
select col1,col2,col3,...
from tbltrn_product
There is the basic:
INSERT INTO tbltrn_outward(chalanno, godownsrno, ... )
SELECT
column1
, column2
, ...
FROM tbltrn_product
The syntax mentioned in question is not correct.
Below Query would help if fields in table1, table2 are unique and table3 contains all fields of table1 and 2:
INSERT INTO TABLE3 (SELECT * FROM TABLE1,TABLE2);
Refer fiddle here:http://sqlfiddle.com/#!2/e3cc4/1
Below query would help if fields overlap in table1 and 2:
INSERT INTO TABLE3 (SELECT TABLE2.FIELD1, TABLE1.FIELD2,
TABLE2.FIELD3, TABLE2.FIELD4
FROM TABLE1,TABLE2);
Refer fiddle here:http://sqlfiddle.com/#!2/479f4/1