Update rows where a combination of multiple attributes is IN the table - sql

I want to update the fields of a table WHERE the combination of three other attributes is IN another table. I am having some difficulties with the syntax, so any help is appreciated.

You would normally use EXISTS for this:
SELECT *
FROM a
WHERE EXISTS (
SELECT 1
FROM b
WHERE a.col1 = b.col1 AND a.col2 = b.col2 AND a.col3 = b.col3
)
Convert the above to an UPDATE query.

Related

Can I replace Union all with any kind on joins?

I have the below query for negative testing, But I want to replace the union all if possible.
select A.*
from A
join B
on A.COL1=B.COL1
where B.COL3 is null
union all
select A.*
from A
join B
on A.COL2=B.COL4
where B.COL5 is null;
Need to get data from both SQL without using union all
You could combine the two queries into a single join and collapse the where condition into it:
select A.*
from A
join B on (A.COL1 = B.COL1 and B.COL3 is null) or
(A.COL2 = B.COL4 and B.COL5 is null)
Since you're only after data from Table A you don't need the join to table B at all and can re-write this as an Exists...
SELECT A.*
FROM A
WHERE EXISTS (SELECT 1
FROM B
WHERE A.COL1=B.COL1 and B.COL3 is null)
OR EXISTS (SELECT 1
FROM B
WHERE A.COL2=B.COL4 and B.COL5 is null)
But this has likely has two issues:
I'm pretty sure if you look at the execution plan for both; you'll find the union all is more efficient because it operates at a set level instead of a row level ad the OR needed in this is slower.
This will return 1 record from A instead of 2 from that of a union all. had it been a union; this should/would return the same results and avoid the union. But simply put you want the same data from A twice (or more depending on cardinality of joins)
SELECT A.*
FROM A
JOIN B ON (A.COL1 = B.COL1 OR A.COL2 = B.COL4) AND B.COL3 IS NULL;

MSSQL How to copy data from one table to another with a condition

I'm trying to update table a with data from some of the columns in table b. Column names are matching in both tables, cannot figure out the syntax, can anyone help?
This is what I want to do (expressed out-of-syntax):
UPDATE table_a
SET table_a.col1 = table_b.col1, table_a.col2 = table_b.col2
WHERE table_a.id = table_b.id
Maybe (probably) I would need some kind of JOIN-clause, but I haven't gotten my head around those yet.... :-/
You can update your table using a JOIN of the two tables:
UPDATE table_a a
INNER JOIN table_b b ON a.id = b.id
SET a.col1 = b.col1, a.col2 = b.col2
I see you are on MYSQL. Not sure if the version above works. If not, try:
UPDATE table_a a
INNER JOIN table_b b
SET a.col1 = b.col1, a.col2 = b.col2
WHERE a.id = b.id
Ok, so I found it myself... :-)
MERGE (without using the WHEN NOT MATCHED clause)is the answer to my problem.
My solution:
MERGE INTO table_a
USING table_b
ON a.id=b.id
WHEN MATCHED THEN UPDATE SET
col1 = b.col1, col2 = b.col2;

Seeking a Teradata Merge alternative

I have an existing process where I am using a Merge statement. I now need to add additional columns in one of the tables. I added one of the new fields to Table A's primary index, but that data doesn't exist in Table B, the source of the Merge, so the Merge fails. If I remove the primary index on Table A, Merge also fails.
-- TABLEA Primary Index - COL1,COL2,COL3,COL4,COL5,COL6
-- TABLEB No Primary Index
Merge into TableA
Using TableB
on A.COL1 = B.COL1
AND A.COL2 = B.COL2
AND A.COL3 = B.COL3
AND A.COL4 = B.COL4
This produces error message: "MERGE Failed. [5758] The search condition must fully specify the Target table primary index and partition column(s) and expression must match INSERT specification primary index and partition column(s)."
If I remove the primary key from TableA I get this message: "MERGE Failed. [9252] An invalid statement was attempted on a table without a primary index: Merge-Into NoPI tables is not allowed."
So, If I can't use Merge, as TableB doesn't have some of TableA's Primary Index columns, what are my options? I'm not sure if there are other Teradata functions.
I tried this, but it didn't find the records in TableB, which are not in TableA:
SELECT B.COL1
,B.COL2
,B.COL11
,B.COL8
,B.COL9
,B.COL3
,B.COL4
,'N'
FROM TABLEB B
WHERE NOT EXISTS (SELECT 1
FROM TABLEA A
INNER JOIN TABLEB B
ON B.COL1 = A.COL1
AND B.COL2 = A.COL2
AND B.COL3 = A.COL3
AND B.COL4 = A.COL4)
There's probably no need to add another column to the existing PI, PI <> PK.
Regarding the NOT EXISTS query, it's a non-correlated subquery which results in true if there's any matching row. You need a correlated subquery:
SELECT B.COL1
,B.COL2
,B.COL11
,B.COL8
,B.COL9
,B.COL3
,B.COL4
,'N'
FROM TABLEB B
WHERE NOT EXISTS (SELECT 1
FROM TABLEA A
WHERE B.COL1 = A.COL1
AND B.COL2 = A.COL2
AND B.COL3 = A.COL3
AND B.COL4 = A.COL4)

join clause, match or null

So I have some procs I inherited that I am trying to clean up. One of the things I see over and over in them is the following:
Update Table_A
Set A.ColX = B.Colx
From Table_A A
Join Table_B B on B.col1 =A.col1
and B.col2 = A.col2
Update Table_A
Set A.ColX = B.Colx
From Table_A A
Join Table_B B on a.col1 =b.col1
and B.col2 is null
Now , I have tried to combine these to make them a single query using the following different final lines (not at the same time!):
1) and (B.col2 = A.col2 or B.col2 is null)
2) and (isnull(B.col2,'') = COALESCE(a.col2, ''))
However, it always seems to do one of the updates, not both. I feel like I am missing something rather obvious, Is there a good way to combine these two queries?
thanks
This query should work:
Update Table_A
Set A.ColX = B.Colx
From Table_A A
Join Table_B B on B.col1 = A.col1
and (B.col2 = A.col2 OR or B.col2 is null)
which you said you tried - but you may try it as a SELECT first and see what the results are. That may shed some light on why you're not getting the results you expect.
I would expect the following query to work in SQL Server:
Update A
Set ColX = B.Colx
From Table_A A Join
Table_B B
on a.col1 = b.col1 and
(B.col2 = A.col2 or B.col2 is null);
Notes:
You should use the alias defined in the from clause after the update. My understanding is that if you use the table name and the table is not in the from clause without an alias, then all rows will be updated.
Although I was pretty sure that SQL Server does not support table aliases in the set, I appear to be wrong about that, as this simple SQL Fiddle shows. Perhaps this was not allowed in some ancient version of SQL Server, and the limitation just stuck with me.

How to choose a proper filter for an sql join

If I have table A and table B, each with one column:
A:
col1
1
2
3
1
B:
col1
1
1
4
and I want all rows from A and the matching rows from B, only when the column has non null value in both tables, which one should I use?
select * from A left join B on A.col1 = B.col1 and A.col1 is not null AND B.col1 is not null;
select * from A left join B on A.col1 = B.col1 where A.col1 is not null OR B.col1 is not null;
select * from A left join B on A.col1 = B.col1 and (A.col1 is not null OR B.col1 is not null;)
My guess is that the first and the third are the same and will provide the desired output.
If you want to skip null values and you want to link both tables only on existing values you should use an INNER JOIN, the null check is redundant:
SELECT A.*
FROM A INNER JOIN B ON A.col1 = B.col1
NULL will never match any other value (not even NULL itself), unless the join condition explicitly uses the IS NULL or IS NOT NULL predicates.
In a comment you said you are checking for more than nulls in this case I would probaly take thederived table or CTE approach. Dervied table shown below as you did not specify which database backend, so I don't know if you can use CTEs.
select
from
(select from tablea where test is not null or test <>'' or test<>'N/A') a
JOin
(select from tableb where test is not null or test <>'' or test<>'N/A')b
ON a.col1 = b.col1
You just need
select * from A left join B on A.col1 = B.col1
NULL will never match anything (when not compared with IS NULLand the like), therefore NULL in A won't match anything in B.
Since you want all the rows from A, below query should work:
select * from A left outer join B on A.col1 = B.col1 where A.col1 is not null and A.col1<>'N/A' and A.col1<>''
http://sqlfiddle.com/#!2/98501/14