SQL Update after Joining Two Tables - sql-server

I am new to SQL, using Microsoft SQL Server Management Studio.
I am trying to write a SQL statement that performs an update after two tables are joined.
I have two tables: myTable1 and myTable2. Both share a field MyID, which is going to be the field that I join on. myTable1 contains a column called BitToUpdate. And MyTable2 contains a column called BitToCheck.
I want to set BitToUpdate in myTable1 to be 1 where BitToCheck in myTable2 is 1 as well.
Here is what I have:
SELECT M.MyID, BitToUpdate, BitToCheck
INTO #temp_table
FROM myTable1 as T1
LEFT JOIN myTable2 as T2
ON M.MyId = PO.MyId
So first I tried to join the two tables myTable1 and myTable2 on their IDs, and store the result in a temporary table.
Next, I want to update BitToUpdate to be 1 where BitToCheck is 1.
So to do that in the temporary table, I have:
UPDATE #temp_table
SET
`BitToUpdate` = 1
WHERE
`BitToCheck` = 1
This updates the BitToUpdate successfully in #temp_table. However, when I do a select on myTable1, I find that BitToUpdate is not changed. I suppose this makes sense as #temp_table isn't really a "pointer"....
But what would be the correct way to approach this join and update?

You don't need to use a LEFT JOIN here, since you are checking on a condition from table 2, so an INNER JOIN should be better here.
UPDATE T1
SET T1.BitToUpdate = 1
FROM myTable1 T1
INNER JOIN myTable2 T2
ON T1.MyId = T2.MyId
WHERE T2.BitToCheck = 1

What you are doing in your first query is updating a temp table named #temp. the updates never go to the actual table myTable1 or mayTable2. To update records while joining with other tables try this:
UPDATE T1
SET T1.BitToUpdate = 1
FROM myTable1 as T1
LEFT JOIN myTable2 as T2 (ON T1.MyId = T2.MyId)
WHERE T2.BitToCheck = 1

--SELECT M.MyID, BitToUpdate, BitToCheck
--INTO #temp_table
update t1
set t1.BitToUpdate = 1
FROM myTable1 as T1
LEFT JOIN myTable2 as T2
ON t1.MyId = t2.MyId
where t2.bittocheck = 1

UPDATE T1
SET BitToUpdate=1
FROM myTable1 T1
LEFT JOIN myTable2 T2
ON T1.MyId=T2.MyId
WHERE T2.BitToCheck=1

Related

How to write an SQL query for this scenerio?

I'm trying to write a query where I want all the items in table1 that are in table2 which meets the first inner join criteria below (this is work find).
Then I want to check table3 to if there are exceptions. Exceptions are base on reference numbers (REF_NO). If the reference number exist in table3 then I need to check if the store number (STORE_NO) matches. If they match then I want the matching record from table1. If not then exclude the matching record from table1.
However, if there reference number DOES NOT exist in table3 then I want the record from table1 that match with table2.
Thanks
USE master
GO
table1
table2
table3
SELECT
T1.TERMINAL,
T1.OPERATOR,
T1.TRANS_NO,
T1.SEQ_NO,
T1.STORE_NO,
T2.REF_NO,
T2.SDATE,
T2.EDATE,
T1.POS_DATE,
T1.ITEM,
T1.ITYPE,
T1.SOLD_QTY,
T1.PRICE,
T2.OI_AMT
FROM [table1] As T1
INNER JOIN [table2] As T2
ON (T1.ITEM = T2.ITEM) And (T1.POS_DATE BETWEEN T2.SDATE And T2.EDATE)
INNER JOIN [table3] As T3
ON (T2.REF_NO = T3.REF_NO) And (T1.STORE_NO = T3.STORE)
SELECT
T1.TERMINAL,
T1.OPERATOR,
T1.TRANS_NO,
T1.SEQ_NO,
T1.STORE_NO,
T2.REF_NO,
T2.SDATE,
T2.EDATE,
T1.POS_DATE,
T1.ITEM,
T1.ITYPE,
T1.SOLD_QTY,
T1.PRICE,
T2.OI_AMT
FROM [table1] As T1
INNER JOIN [table2] As T2
ON T1.ITEM = T2.ITEM
AND T1.POS_DATE > T2.SDATE
AND T1.POS_DATE <= T2.EDATE
WHERE EXISTS ( SELECT TOP (1) 1
FROM table3 as T31
WHERE T2.REF_NO = T31.REF_NO
AND T1.STORE_NO = T31.STORE)
OR NOT EXISTS ( SELECT TOP (1) 1
FROM table3 as T32
WHERE T2.REF_NO = T32.REF_NO)
This should work, it checks both of your conditions. I also would encourage you not to use BETWEEN clause and specify date ranges using two conditions.

How to write Inner Join Query in dqMan?

We have two tables dbo.MONITOR (Reg. table) & sum_file_folder (documentum table)
dbo.MONITOR
- FILE_ID
- STATUS
sum_file_folder
- object_name
- file_status
where, FILE_ID & object_name are same fields in both tables.
So these Inner Join Queries are not working...
update dbo.MONITOR t1 objects set t1.STATUS = (select file_status from sum_file_folder t2 where t1.FILE_ID=t2.object_name)
UPDATE t1 OBJECTS SET t1.STATUS = t2.file_status from sum_file_folder t1 INNER JOIN dbo.MONITOR t2 ON t1.object_name = t2.FILE_ID
Looks like some syntax and table alias issue in your query.
Can you try the query below:
UPDATE t1
SET STATUS = t2.file_status
FROM dbo.MONITOR t1
INNER JOIN dbo.sum_file_folder t2 ON t2.object_name = t1.FILE_ID
You can use this code to update the status in your table.
UPDATE t1
SET t1.STATUS = t2.file_status
FROM dbo.MONITOR t1
INNER JOIN sum_file_folder t2 where t1.FILE_ID=t2.object_name
When you are using your own tables, you can safely do an update directly to database - no need for DQL (sum_file_folder must be a custom table - I haven't seen that before).
If you are stuck with DQL you could do a EXECUTE exec_sql WITH QUERY 'your-sql-update-statement'
Just be careful - this is auto-committed.

Not in Not exists

I have three tables
table1 -> xt1, yt1, zt1;
table2 -> xt2
table3 -> yt3, zt3
SELECT xt1, yt1, zt1
From table1, table3
Where xt1
NOT IN
(SELECT DISTINCT table1.xt1 FROM table2 INNER JOIN table1 ON
table1.xt1 = Replace(table2.xt2,',',''))
And table1.yt1 = table3.yt3
AND table1.zt1 = table3.zt3
it is working correctly but i take long time.
if i replace NOT IN with Not exists it return empty set.
SELECT xt1, yt1, zt1
From table1, table3
Where Not exists
(SELECT DISTINCT table1.xt1 FROM table2 INNER JOIN table1 ON
table1.xt1 = Replace(table2.xt2,',',''))
And table1.yt1 = table3.yt3
AND table1.zt1 = table3.zt3
the results of the second select should be 6 rows but it returns notiong with not exists.
also if i tried to change the compare part to
table1.xt1 != Replace(table2.xt2,',','') and remove the NOT IN
select it get outof memory error.
So is this the best way to write my query and why it return empty set with Not exists
thank you.
Ok, first of all, I changed your implicit join to an explicit one. Then I fixed the NOT EXISTS so it correlates to the outer table1:
SELECT t1.xt1, t1.yt1, t1.zt1
FROM table1 AS t1
INNER JOIN table3 AS t3
ON t1.yt1 = t3.yt3
AND t1.zt1 = t3.zt3
WHERE NOT EXISTS ( SELECT 1
FROM table2 AS t2
INNER JOIN table1 AS t1_1
ON t1_1.xt1 = REPLACE(t2.xt2,',','')
AND t1_1.xt1 = t1.xt1) ;
which can be simplified further to:
SELECT t1.xt1, t1.yt1, t1.zt1
FROM table1 AS t1
INNER JOIN table3 AS t3
ON t1.yt1 = t3.yt3
AND t1.zt1 = t3.zt3
WHERE NOT EXISTS ( SELECT 1
FROM table2 AS t2
WHERE t1.xt1 = REPLACE(t2.xt2,',','')
) ;
You need to select IN or exist depending upon the size of inner query. when there is a outer query and inner-sub-query, if the result of sub query is small, In is preferred as outer query is selected based upon result of sub-query.
if the result of sub-query is large, exist is preferred as outer query is evaluated first.

Insert column from one table to other using Join

I need to insert 3 columns from one table to another, using JOIN by 3 fields: name, surname and age
I need update column status, status1 and status2 in table_2 with values from table_1
IF
table_1.name = table_2.name
table_1.surname = table_2.surname
table_1.age= table_2.age
UPDATE t2
SET
t2.[status]=t1.[status]
,t2.[status1]=t1.[status1]
,t2.[status2]=t1.[status2]
FROM [table_1] t1
INNER JOIN [table_2] t2
ON (t1.name=t2.name AND t1.surname=t2.surname AND t1.age=t2.age)
As you mentioned in comments that these table from different databases, then please change only the two line like.
FROM [yourDataBase1Name].[dbo].[table_1] t1
INNER JOIN [yourDataBase2Name].[dbo].[table_2] t2
Just update the table with Join.
it will be something like this:
UPDATE t2
SET t2.status = t1.status,
t2.status1 = t1.status1,
t2.status2 = t1.status2
FROM t2 JOIN t1 on (t1.first_name = t2.first_name AND t1.last_name = t2.last_name AND t1.age = t2.age);
Look here for more information:SQL update query using joins
SQL Fiddle: http://sqlfiddle.com/#!3/b3951/1

Join two tables only if the first contains certain values if not join another

I am trying to write a query that join to a TableA another TableB if TableA.Column1 contains numeric values and Join to TableA another TableC if TableA.Column1 contains varchar values.
Is there a way to write such a query?
How about something like this? You will need to cast the columns appropriate to some middle ground.
SELECT *
FROM TableA a
INNER JOIN TableB b ON b.Columns1 = a.Column1
AND ISNUMERIC(a.Column1) = 1
WHERE 1=1
UNION
SELECT *
FROM TableA a
INNER JOIN TableC c ON c.Columns1 = a.Column1
AND ISNUMERIC(a.Column1) = 0
The table design sounds questionable, but I think this query is a simple way to achieve what you're asking for.
SELECT
TableA.Column1,
TableB.Column2,
TableC.Column2,
ISNULL(TableB.Column2, TableC.Column2)
FROM TableA
LEFT OUTER JOIN TableB ON
ISNUMERIC(TableA.Column1) = 1
AND TableA.Column1 = TableB.Column1
LEFT OUTER JOIN TableC ON
ISNUMERIC(TableA.Column1) = 0
AND TableA.Column1 = TableC.column1
As Mike Cheel points out, you may need to do some casting.
Also, with this approach you will need to consider the possibility that there is a record in TableA that does not match anything in TableB or TableC, because this is using outer joins. If you don't want those records in your result, you can just exclude them with a condition in your WHERE clause.
Along the lines of JNK's comment, here's a way where you could go about it which at least tries to encapsulate the design issue a bit, by add 2 Computed columns to your table, which represent placeholders for the INT and VARCHAR foreign keys.
ALTER TABLE MyTable ADD IntJoinColumn AS
CASE WHEN ISNUMERIC(BadJoinColumn) = 1
THEN CAST(BadJoinColumn AS INT)
ELSE NULL
END;
ALTER TABLE MyTable ADD VarCharJoinColumn AS
CASE WHEN ISNUMERIC(BadJoinColumn) = 1
THEN NULL
ELSE BadJoinColumn
END;
You can then join in a more 'readable' manner, like so:
SELECT mt.*
FROM MyTable mt
INNER JOIN MyIntJoinTable ON IntJoinColumn = MyIntJoinTable.Id
UNION ALL
SELECT mt.*
FROM MyTable mt
INNER JOIN MyVarCharJoinTable ON VarCharJoinColumn = MyVarCharJoinTable.VarCharId;
SQLFiddle Here
(The NULL mapping has the effect of filtering out the 'incorrect' data types by eliminating them during the INNER JOIN.)

Resources