What kind of join is used in a Vertica UPDATE statement? - sql

Vertica has an interesting update syntax when updating a table based on a join value. Instead of using a join to find the update rows, it mandates a syntax like this:
UPDATE a
SET col = b.val
where a.id = b.id
(Note that this syntax is indeed mandated in this case, because Vertica prohibits us from using a where clause that includes a "self-join", that is a join referencing the table being updated, in this case a.)
This syntax is nice, but it's less explicit about the join being used than other SQL dialects. For example, what happens in this case?
UPDATE a
SET col = CASE 0 if b.id IS NULL ELSE b.val END
where a.id = b.id
What happens when a.id has no match in b.id? Does a.col not get updated, as though the condition a.id = b.id represented an inner join of a and b? Or does it get updated to zero, as if the condition were a left outer join?

I think Vertica uses the Postgres standard for this syntax:
UPDATE a
SET col = b.val
FROM b
whERE a.id = b.id;
This is an INNER JOIN. I agree that it would be nice if Postgres and the derived databases supported explicit JOINs to the update table (as some other databases do). But the answer to your question is that this is an INNER JOIN.
I should note that if you want a LEFT JOIN, you have two options. One is a correlated subquery:
UPDATE a
SET col = (SELECT b.val FROM b whERE a.id = b.id);
The other is an additional level of JOIN (assuming that id is unique in a):
UPDATE a
SET col = b.val
FROM a a2 LEFT JOIN
b
ON a2.id = b.id
WHERE a.id = a2.id;

Related

Filter on the column on which two tables are joined

Are next two queries going to return same result set?
SELECT * FROM tableA a
JOIN tableB b
ON a.id = b.id
WHERE a.id = '5'
--------------------------------
SELECT * FROM tableA a
JOIN tableb b
ON a.id = b.id
WHERE b.id = '5'
Also, will answer be different if LEFT JOIN is used instead of JOIN?
As written, they will return the same result.
The two will not necessarily return the same result with a left join.
Yes the result will be the same.
With a left join you will get every dataset of both table who got a ID.
With a join (Inner Join) you will get only the dataset's who a.id = b.id.
This site will explain you how to join https://www.w3schools.com/sql/sql_join.asp
Yes they will. A simple join works like an inner join by default. It checks for instances where the item you're joining on exist on both tables. Since you're joining on where a.id=b.id the results will be the same.
If you change the type of join to a left, the results will include all a.id's regardless of whether they are equal to 5.

MS-Access SQL : Join expression not supported

I have 2 tables A and B. I want to create a third one, C. C must contain each record that is in A but not in B, and each record that is in A and B.
I've tried the following :
SELECT A.* INTO C FROM (A INNER JOIN B ON A.Id = B.Id) LEFT JOIN B ON A.Id = B.Id WHERE B.Id IS NULL;
But it gives me the error message : JOIN expression not supported.
When there's only the INNER JOIN or the LEFT JOIN, it works perfectly. But for some reason when I combine both with the brackets, it doesn't work.
I believe I am using MS-Access 2013, if that helps.
By the way, I'm an Access and an SQL newbie.
The correct logic is:
SELECT A.* INTO C
FROM A LEFT JOIN
B
ON A.Id = B.Id
WHERE B.Id IS NULL;
You do not need two joins. My guess is that the problem with your query is that B appears twice in the FROM clause, without a table alias. MS Access doesn't know what the second B refers to.

Remove Duplicate Code from UPDATE

I have the following query.
UPDATE A SET b = (SELECT b FROM B WHERE A.a_id = B.a_id AND B.value = ?)
This might fill A with NULL values if no a_id exists in B where value = ?. but this is okay, because before executing this query, it is certain that A.b contains only NULL values to begin with.
However, I need the number of updated columns to reflect the number of updates performed. So I changed it into this:
UPDATE A SET b = (SELECT b FROM B WHERE A.a_id = B.a_id AND B.value = ?)
WHERE EXISTS (SELECT b FROM B WHERE A.a_id = B.a_id AND B.value = ?)
I don't like this solution, because now I have duplicate code and have to fill the parameter multiple times. This gets even uglier when the where clause gets more complicated.
Is there a way to get rid of this duplicate code?
(BTW I'm on Oracle 10, but I prefer DB independent solutions)
Updat using an inner join
UPDATE A
INNER JOIN B ON A.a_id = B.a_id
SET A.b = B.b
WHERE B.value = ?
If that isn't allowed with your particular RDBMS, perhaps you could SELECT the old and new values into an aliased table expression and update using that. See Update statement with inner join on Oracle

Joins in Oracle: Which field on which side of an = sign?

When joining tables with either the ANSI-89 (old) or the ANSI-92 ("new") method of joining tables, does it matter which side you place the fields from the 2 joining tables.
For example, is it better to do:
From
TABLE_1 A
Join
TABLE_2 B
on A.ID = B.ID
Or is the following better?
on B.ID = A.ID
Is it simply aesthetics? Or does it effect how the joins work?
EDIT: For further clarification, what about Left Joins? For example:
From
TABLE_1 A
Left Join
TABLE_2 B
on A.ID = B.ID
Is this the same as
on B.ID = A.ID
However, if using ANSI-89 Where A.ID = B.ID (+) is NOT the same as Where B.ID = A.ID (+) since the second joins A ONTO B?
It makes no difference. The only time the order matters is when you are doing LEFT and RIGHT OUTER joins, but those keywords all fall before the ON keyword.
The = operator is symmetric, so a.id = b.id is exactly the same as b.id = a.id. Personally, I prefer having the fields from the driving table (the one in the FROM clause) on the left hand side of the operator, but that's purely an aesthetic preference.

How to use oracle outer join with a filter where clause

If i write a sql:
select *
from a,b
where a.id=b.id(+)
and b.val="test"
and i want all records from a where corresponding record in b does not exist or it exists with val="test", is this the correct query?
You're much better off using the ANSI syntax
SELECT *
FROM a
LEFT OUTER JOIN b ON( a.id = b.id and
b.val = 'test' )
You can do the same thing using Oracle's syntax as well but it gets a bit hinkey
SELECT *
FROM a,
b
WHERE a.id = b.id(+)
AND b.val(+) = 'test'
Note that in both cases, I'm ignoring the c table since you don't specify a join condition. And I'm assuming that you don't really want to join A to B and then generate a Cartesian product with C.
Move the condition into the JOIN clause and use the ANSI standard join pattern.
SELECT NameYourFields,...
FROM A
LEFT OUTER JOIN B
ON A.ID = B.ID
AND B.VAL = 'test'
INNER JOIN C
ON ...
A LEFT OUTER JOIN is one of the JOIN operations that allow you to specify a join clause. It preserves the unmatched rows from the first (left) table, joining them with a NULL row in the shape of the second (right) table.
So you can do as follows :
SELECT
FROM a LEFT OUTER JOIN b
ON a.id = b.id
--Note that you have used double quote "test" which is not used for varchar in SQL you should use single quote 'test'
AND b.val = 'test';
SELECT * FROM abc a, xyz b
WHERE a.id = b.id
AND b.val = 'test'