SQL JOIN that uses OR in the ON statement - sql

I’m running a SQL query on Google BigQuery and want to do this kind of SQL command:
SELECT ... FROM A JOIN B
ON A.col1=B.col1 AND (A.col2=B.col2 OR A.col3=B.col3)
This fails though with the error:
Error: ON clause must be AND of = comparisons of one field name from each table, with all field names prefixed with table name.
Is there a way to rewrite the SQL to get this kind of functionality?

Turns out this works, which is equivalent to a UNION ALL statement in Google BigQuery. Not sure how to do it if you just want a UNION, since DISTINCT is actually not supported in BigQuery. Luckily it's enough for me as is.
SELECT ... FROM
(SELECT ... FROM A JOIN B ON A.col1=B.col1 AND A.col2=B.col2),
(SELECT ... FROM A JOIN B ON A.col1=B.col1 AND A.col3=B.col3)

This should work:
SELECT ... FROM A CROSS JOIN B
WHERE A.col1=B.col1 AND (A.col2=B.col2 OR A.col3=B.col3)

Related

Oracle SQL Language Reference Merge/Subquery Documentation Error?

When using the merge::= MERGE INTO ... USING subquery t_alias it appears one must enclose the subquery in parenthesis like MERGE INTO ... USING (subquery) t_alias. However, the Oracle SQL Language Reference documentation's syntax diagram for subquery::= appears to show that an optional path (via query_block) does not require parenthesis. That is the documentation appears to allow both versions.
For example:
This following is invalid, but allowable per the documentation.
MERGE INTO tblA A
USING SELECT col FROM tblB B -- ORA-00903 invalid table name and "SELECT" is highlighted.
ON (A.id = B.id)
...
The following is valid (and also allowable per the documentation).
MERGE INTO tblA A
USING (SELECT col FROM tblB) B
ON (A.id = B.id)
...
According to How to Read Syntax Diagrams
If the syntax diagram has more than one path, then you can choose any path.
Is there an Oracle SQL Language Reference documentation error?
Thanks in advance.
In MERGE query, the operand used after USING clause is not exactly a sub query. It actually defines a table. For example: if you want to update a table from the values from another table.
MERGE INTO tblA A
USING tblB B
ON (A.id = B.id)
...
In case tblB has very huge amount of data and you want to optimise the
perfomance, you can use a query to fetch required columns from the table.
MERGE INTO tblA A
USING (SELECT col1, col2, col3 FROM tblB) B -- here we are not using complete table,
instead we are using only required columns from the table
ON (A.id = B.id)
...
Merge is also similar to join, below is the better way of understanding
select * from tblA A
inner join tblB B
ON (A.id = B.id);
or
select * from tblA A
inner join (SELECT col1, col2, col3 FROM tblB) B
ON (A.id = B.id);
The reason you get invalid table name is, when you do not enclose the select statement in brackets, Oracle will not know the aliases of the table you are using. So always enclose a bracket when you have a certain conditions in the query.

PostgreSQL condition: one table equals another

I have seen commands like DELETE FROM A USING B WHERE A=B in PostgreSQL scripts. Can anyone point me a reference and explain the logic behind the A=B? Is it a good way to match all columns of two tables? Many thanks!
This is a form of JOIN -- because Postgres doesn't support "join" for this purpose.
The equivalent SELECT would be:
select . . .
from a join
b
on a.a = b.b;
You can also express this using a correlated subquery:
delete from a
where exists (select 1 from b where b.b = a.a);

Simple way to join many tables with similar names in SSMS?

I have many tables that are all named similarly (like "table1" "table2" "table3" etc.) and I need to use all of them in a query. They all contain the same two variables ("ID" and "date") that they are joined on.
There are at least 25 tables of this sort and I have read-only access to the database so I can't combine them or even create a view that would do so.
My question is: Is there a simple shortcut I can use to join all these tables? If this were SAS I would create a macro, but I'm using Microsoft SQL Server Management Studio 2012.
Instead of having to do this:
select *
from table1 a
join table2 b on a.id=b.id and a.date=b.date
join table3 c on b.id=c.id and b.date=c.date
join ....
join ....
join table25 y on x.id=y.id and x.date=y.date
I'd like to do something like:
select *
from merge(table1 - table25) using(id, date)
Replacing the "merge" statement above with whatever is appropriate. Is such a thing possible?
As pointed out in the comments, the succinct syntax you are looking for doesn't exist.
The only way to shorten the SQL that takes advantage of the fact that the joining columns are all named the same would involve using the using keyword:
select *
from table1 a
join table2 b using (id, date)
join table3 c using (id, date)
join ....
join ....
join table25 y using (id, date)
But sadly, even that won't work for you, because the using keyword is not recognized in SQL Server. It does work in other popular databases though.

Does BigQuery support SubQueries?

In my SQL FROM clause, I want to use a dynamically created table via a subquery:
Select A.Field1,B.Field2
FROM TableA as A, (select Field1,Field2 from TableB) B
Where A.Field1 = B.Field1
Does BigQuery support this?
You don't need a subquery for this:
Select A.Field1,B.Field2
FROM TableA as A join
TableB as B
on A.Field1 = B.Field1;
But yes, according to the reference manual, BigQuery does support subqueries.
Yes it does, I remember doing something like
SELECT a ,b
FROM Tablea
WHERE a not IN (SELECT a FROM Tableb)
First let's formally fix your query (assuming you are using BigQuery Legacy SQL)
Please note that in Legacy SQL comma is used not as JOIN but rather as UNION ALL
So you query, to work, should look like below
SELECT A.Field1, B.Field2
FROM TableA AS A
JOIN (SELECT Field1, Field2 FROM TableB) AS B
ON A.Field1 = B.Field1
Of course in your particular example you don’t need subselect, but I think it is just simplified example so I am not going this direction and other answers already pointed to this anyway
Finally, about subqueries in BigQuery
BigQuery Legacy SQL supports very limited use of Subqueries - know as table subquery - in FROM and FLATTEN and semi- or anti-semi-JOIN (with only one field)
You can find details here https://cloud.google.com/bigquery/query-reference
From the other hand BigQuery Standard SQL provides reach support for Subqueries - for table subqueries as well as expression subqueries
You can see more here https://cloud.google.com/bigquery/sql-reference/query-syntax#subqueries
Note: BigQuery Standard SQL version is in Alpha yet

Oracle 22 Joins or over is not allowed in a select statement ? ORA-01445

ORA-01445: cannot select ROWID from, or sample, a join view without a
key-preserved table
I have a long select statement on ORACLE 10g.
According to this error statement, I have seen some answers on google. One of the answer is saying that ;
* limit on number of tables in join I 've run across an unusual bug
(4204878/ 3765373/ 3004824) on Oracle 9.2.0.5. When more than 22 ANSII
joins are done in a select statement an ORA-01445 occurs. According to
Support "1- One so
I count the number of joins inside the whole select block; is 23 (after select and after where clause).
The SP which has this "selec"t statement was working perfectly until I added this new join after where clause...
For short, I ve tested by disabling one of existing join and enabled my newly added join and SP worked.
What do you think are there really any limit ?
** I can't give you the web site addess since it is always found smearing by the users of StackOverflow..
I've run into these bugs a couple of times. It happened a lot in 9i with ANSI joins and i've found it happens less frequently in 10g.
One workaround is to rewrite the join to use the "old" join synthax, specifically outer joins as APC pointed out:
SELECT *
FROM a, b
WHERE a.a_id = b.a_id (+)
I've solved that issue by just selecting the columns that I used on query.
From this:
select a.column1, b.column3
from a
join b on b.column2 = a.column2
To this:
select a.column1, b.column3
from (select column1, column2 from a) a
join (select column2, column3 from b) b on b.column2 = a.column2