I'm trying to update multiple columns in a MS SQL statement using a sub-query. A search led me to something like:
UPDATE table1
SET col1 = a.col1, col2 = a.col2, col3 = a.col3 FROM
(SELECT col1, col2, col3 from table2 where <expression>) AS a
WHERE table1.col1 <expression>
Link
My problem is that in the inner WHERE expression I need a reference to a specific field in table1:
UPDATE table1
SET col1 = a.col1, col2 = a.col2, col3 = a.col3 FROM
(SELECT col1, col2, col3 from table2 where table1.col0 = table2.col0) AS a
WHERE table1.col1 <expression>
When I run that query I get "The multi-part identifier "table1.col0" could not be bound.
". Apparently when using that syntax SQL cannot bind the current table1 record in the subquery. Right now I am repeating the subquery for each field and using the syntax:
UPDATE table1
SET col1 = (subquery), col2 = (subquery)...
But that executes the subquery (which is very expensive) once per column, which I would like to avoid.
Any ideas?
in sql server, you can use a from clause in an update query. Join the tables as you would in a select. The table you are updating must be included in the joins.
update table_1
set field_1 = table_2.value_1
from table_1
inner join table_2
on (table_1.id = table_2.id)
Or if you dislike the join syntax this will also work:
UPDATE table1
SET col1 = a.col1, col2 = a.col2, col3 = a.col3
FROM table1, table2 as a
WHERE table1.col0 = a.col0
AND table1.col1 <expression>
Your car use CROSS APPLY command to update multiple columns from sub select
UPDATE t1
SET t1.col1 = a.col1, t1.col2 = a.col2, t1.col3 = a.col3
FROM table1 t1
CROSS APPLY
(SELECT col1, col2, col3 from table2 where table1.col0 = table2.col0) a(col1,col2,col3)
Related
I was wondering about the efficiency of a couple of different queries. The task is to pull multiple tables together that must be equal from multiple columns different. I am curious about what is the best way to approach this from an efficiency standpoint.
I have already checked this out, but it doesn't say anything about multiple column where clauses
SQL WHERE.. IN clause multiple columns
and this solution shows doesn't comment on the efficiency or best practices of the solution, and doesn't include a solution where the final query is a join from the two tables
Two columns in subquery in where clause
select ID, col1, col2, col3
from table1 a
left join
(select ID, col1, col2, col3 from table2) b on a.col1 = b.col1
where a.col2 = b.col2
and a.col3 = b.col3
or
select ID, col1, col2, col3
from table1 a
left join
(select ID, col1, col2, col3
from table2) b on a.col1 = b.col1
and a.col2 = b.col2
and a.col3 = b.col3
You do not need to do a join on a sub-select. You were very close on the second sample query. Because of the join based on 3 columns, I would make sure that the second table also has a single index using all 3 columns for optimal performance. Ex: Index on ( col1, col2, col3 ), and not 3 individual indexes, one for each column.
Also, try not to use aliases like a, b, c, unless it really correlates to the name of your table like "Accounts a", "Business b", "Customers c". Use an alias on your table references such as the abbreviation more closely matches its source.
select
t1.ID,
t1.col1,
t1.col2,
t1.col3,
t2.WhatColumnFromSecondTable,
t2.AnotherColumnFromTable2,
t2.AnythingElse
from
table1 t1
left join table2 t2
on t1.col1 = t2.col1
and t1.col2 = t2.col2
and t1.col3 = t2.col3
Then, if you are only looking for specific things within, you would add a WHERE clause to further filter your data down.
I have two tables :
Table1 with 5 columns (col1, col2, col3, col4, val1) and Table2 with Table1 with 5 columns (col1, col2, col3, col4, val2).
1. The Table1.val1 doesn't contain any value.
2. For both Table1 and Table2, col1, col2, col3 and col4 are the same and they are the primary key.
What I would like to do, is to update the Table1.val1 with the sum(Table2.val2) when Table1.col1 = Table2.col1 and Table1.col2 = Table2.col2 and Table1.col3 = Table2.col3 and Table1.col4 = Table2.col4.
I did something like :
UPDATE Table1
SET val1 = (
select t_sommevbrute.sumvalbrute from (
Select col1,col2,col3,col4,SUM(val2) sumvalbrute
From Table2
Where col3 = 2014 And col2=51
GROUP BY col1, col2, col3, col4) t_sommevbrute
WHERE Table1.col1 = t_sommevbrute.col1
and Table1.col2 = t_sommevbrute.col2
and Table1.col3 = t_sommevbrute.col3
and Table1.col4 = t_sommevbrute.col4)
But related to this question: Oracle SQL: Update a table with data from another table , I should have WHERE EXISTS clause.
Any help please!!
Thanks.
You can do this in following way:-
With Use of Temp Table:-
First Create Temp Table:-
Create table temp1 as
Select col1,col2,col3,col4,SUM(val2) as sumvalbrute
From table2
Where col3 = 3 And col2=2
GROUP BY col1, col2, col3, col4;
And then use Temp table to update Main Table1:-
UPDATE table1 SET table1.val1 = (SELECT temp1.sumvalbrute
FROM temp1
WHERE Table1.col1 = temp1.Col1
AND Table1.col2 = temp1.Col2
AND Table1.col3 = temp1.Col3
AND Table1.col4 = temp1.Col4);
SQL Fiddle :- http://sqlfiddle.com/#!4/4864d/5
WithOt Use of Temp Table:-
UPDATE table1 SET table1.val1 = (SELECT temp1.sumvalbrute
FROM
(Select col1,col2,col3,col4,SUM(val2) as sumvalbrute
From table2
Where col3 = 3 And col2=2
GROUP BY col1, col2, col3, col4) temp1
WHERE Table1.col1 = temp1.Col1
AND Table1.col2 = temp1.Col2
AND Table1.col3 = temp1.Col3
AND Table1.col4 = temp1.Col4);
SQL Fiddle:- http://sqlfiddle.com/#!4/c9286/2
You can simplify your query greatly:
UPDATE Table1
SET val1 = (select SUM(val2)
from Table2 t
where Table1.col1 = t.col1 and
Table1.col2 = t.col2 and
Table1.col3 = t.col3 and
Table1.col4 = t.col4
)
Where col3 = 2014 And col2 = 51;
You could use where exists. The purpose is to prevent NULL values when there is no match. However, I think pulling the where clause outside probably solves this problem. I note that the where clause is using the same values as the correlation conditions.
You can try this:
UPDATE t1 SET t1.val1 = SUM(t2.val2)
FROM table1
INNER JOIN table2 t2 ON t2.col1 = t1.col1
and t2.col2 = t1.col2
and t2.col3 = t1.col3
and t2.col4 = t2.col4
This kind of update can be achieved ALSO using MERGE statement:
Merge into Table1 using ( select SUM(val2) as val2, t.col1, t.col2, t.col3, t.col4
from Table2 t
group by t.col1, t.col2, t.col3, t.col4
) t -- This is the alias for table 2
on ( Table1.col1 = t.col1
and Table1.col2 = t.col2
and Table1.col3 = t.col3
and Table1.col4 = t.col4
)
when matched then
UPDATE Table1.val1 = t.val2 --HERE IS YOUR **UPDATE**
where Table1.col3 = 2004
and Table1.col2 = 51
;
commit;
Please don't forget to ADD ALIASES to the tables, and a good COMMIT after this code
This solution avoid you from create temporary tables, and works pretty well
Best regards.
I need to copy a table into a new table on SQL server 2008.
Also, add a new column into the new table.
The values of the new column depends on the compare result between the new table and another table.
Example,
Table1:
col1 col2 col3
abc 346 6546
hth 549 974
Expected Table1_new:
col1 col2 col3 col4
abc 346 6546 1
hth 549 974 0
Table2:
col1
abc
sfsdf
If Table2's col1 appear in Table1 col1, mark col4 as 1 in Table1_new, else mark as 0.
The code does not work
SELECT *,
(
SELECT 1 as col4
FROM Table2 as a
INNER JOIN Table1 as b
on b.col1 = a.col1
SELECT 0 as col4
FROM Table2 as a
INNER JOIN Table1 as b
on b.col1 <> a.col1 # I do not know how to do this !!!
)
INTO table1_new
FROM table1
Any help would be appreciated.
You could use an outer join:
SELECT table1.col1, col2, col3,
CASE WHEN table2.col1 IS NULL THEN 0 ELSE 1 END AS col4
INTO table1_new
FROM table1
LEFT OUTER JOIN table2 ON table1.col1 = table2.col1
You can do this in several ways. The following uses an exists clause in a case statement:
insert into table1_new(col1, col2, col3, col4)
select col1, col2, col3,
(case when exists (select 1 from table2 t2 where t2.col1 = t1.col1)
then 1 else 0
end)
from table1 t1;
You can also do this with a left outer join, but you run the risk of duplicates if t2 has duplicates.
INSERT INTO T2
SELECT COL1,COL2,COL3, (COL1+COL2) FROM T1
Note that instead of the (COL1+COL2) section you could run other expressions or possibly even a function.
Try something like this using CASE
SELECT
CASE
WHEN b.col1 = a.col1 THEN 1
ELSE 0
END as col4
FROM Table1 as a
LEFT JOIN Table2 as b
on b.col1 = a.col1
EDIT: Table1 should be the left table as mentioned in #Muerniks answer.
In addition to what the others already suggested: If you can't solve the problem in one step, try to make smaller steps. E.g. first initialize Table1.col4 with zero:
INSERT INTO Table1_new (col1,col2,col3,col4)
SELECT col1,col2,col3,0
FROM Table1
After that you will only need to identify the records which have matching partners in Table2 which is a classical inner join:
UPDATE t1 SET col4=1
FROM Table1_new t1
JOIN Table2 t2 ON t2.col1=t1.col1
I'm trying to determine if there is a better way to do this in SQL. My goal is to run one query which returns two values that are to be used for another query. See below
select *
from table2
where col1 =
( select col1
from table1
where id = 123 )
and col2 =
( select col2
from table1
where id = 123 );
Is there a way to simplify this code by either doing a where clause that checks both values against one nested query, or by running the first querying and somehow setting the values of col1 and col2 to variables that I can use in the second query?
You can do
select *
from table2
where (col1, col2) = (select col1, col2
from table1
where id = 123)
SELECT DISTINCT a.*
FROM table2 a
INNER JOIN table1 b
ON a.col1 = b.col1
AND a.col2 = b.col2
WHERE b.id = 123
you can simply use query as below
select t2.* from table2 t2,table1 t1 where t1.col1=t2.col1 and
t1.col2=t2.col2 and t1.id=123
Seems like you've got it backwards. Since you know exactly what you want from table1 (so, presumably, the query is smaller), you should start by getting the data from table1, then join the releveant rows from table2:
select table2.*
from table1
inner join table2
on table2.col1 = table1.col1
and table2.col2 = table1.col2
where table1.id = 123
I try to update one table based on values found in another table. The following works:
UPDATE table1 SET col1 = ( SELECT col1 from table2 WHERE table2.col1 = table1.col1 );
I want to do the same using several columns. I thought the following should bring the desired result"
UPDATE table1 SET (col1, col2) = ( SELECT col1, col2 from table2 WHERE table2.col1 = table1.col1 );
but I get a
syntax error at or near "SELECT"
LINE 1: UPDATE table1 SET (col1, col2) = ( SELECT col1, col2 f...
Any help appreciated.
This should work:
update table1 t1
set col1 = t2.col1,
col2 = t2.col2
from table2 t2
where t1.col1 = t2.col1;
SQL Fiddle Demo
With that said, no need to update col1 = t2.col1 since that is your join criteria.