I have two tables:
t1: (name, dt, value1)
t2: (name, dt, valuu2)
I want to inner join on the column name
and left join on the column dt
. In other words:
SELECT *
FROM t1 INNER JOIN t2 on t1.name=t2.name
LEFT JOIN t2 on t1.dt=t2.dt
Semantically, I want the following as a correlated SQL query:
SELECT *
FROM t1
LEFT JOIN (SELECT * FROM t2 WHERE t1.name=t2.name) AS t2_ on t1.date = t2_.date
But that is going to be very slow. What would be a good way to implement this?
---EDIT--
Here is a small example as requested:
create or replace table t1(name integer, date integer, value integer);
create or replace table t2(name integer, date integer, value integer);
INSERT into t1 values(1, 10, 100);
INSERT into t1 values(2, 10, 200);
INSERT into t1 values(3, 30, 300);
INSERT into t1 values(4, 40, 400);
INSERT into t2 values(1, 10, 100);
INSERT into t2 values(2, 20, 200);
INSERT into t2 values(3, 30, 300);
SELECT *
FROM t1
LEFT JOIN (SELECT * FROM t2 WHERE t1.name=t2.name) AS t2_ on t1.date = t2_.date
RESULT:
I want to inner join on the column
name
and left join on the columndt
.
Join type is defined in terms of the whole join condition, so what you are asking for does not make sense unless you mean you want to join a table twice.
From your clarification, I think you mean that you want rows for all name
s that are present in both tables, for each name
the columns of t1
and either (i) the row(s) of t2
for which the dates match, or (ii) nulls. You present a version with a correlated inline view, and apparently you are concerned with query performance.
You cannot have both inner and outer semantics with the same join, so you are going to need either a subquery or multiple joins, but it should be possible to do better than the query presented in the question. One possibility would be to perform the outer join, and filter out the unwanted rows based on a(n uncorrelated) suquery:
SELECT *
FROM t1
LEFT JOIN t2
on t1.name=t2.name and t1.dt=t2.dt
WHERE t1 in (select name from t2)
Another possibility would be to use an uncorrelated inline view to form the inner join, and then left-join to that:
SELECT *
FROM (
SELECT DISTINCT t1.*
FROM t1 JOIN t2 ON t1.name = t2.name
) t1_
LEFT JOIN t2
on t1_.name=t2.name and t1_.dt=t2.dt
The SELECT DISTINCT
could be costly there, but that would be difficult to predict even with more information about the database.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments