I've a two tables and a clause where, but I want to bring the left side always independent of the clause where.
Example
table a
-----------------
id
nome
table B
-----------------
id
nome
date
id_a
I've been a query and it works when don't exists value in table B or when the clause WHERE fetch.
select ta.* from table_a ta
left join table_b tb on ta.id = tb.id_a
where
tb.date = '2015-07-05' or tb.id is null
In my table has a registry with tb.date = '2015-07-05'. This query works, but I trying the query with tb.date = '2015-07-04' the query fetch with left side in join, but don't bring the row that have table_b '2015-07-05'.
I want fetch left side in join independent of the clause where.
select ta.* from table_a ta
left join table_b tb on (ta.id = tb.id_a and tb.date = '2015-07-05');
Also, '2015-07-05' is considered a string in Oracle. Always use to_date to compare date values.
Related
I have two tables, Table A has an ID and an Event Date and Table B has an ID, a Description and an Event Date.
Not all IDs in Table A appear in Table B and some IDs appear multiple times in Table B with different Descriptions for each event.
The Description in Table B is an attribute that can change over time, the Event date in Table B is the date that a given ID's Description changes from its default value (kept in another table) to the new value.
I want to find the Description in Table B that matches the Event Date in Table A so, for example
Table Sample Data
A1234 would return Green and A4567 would return Null
I can't create tables here so I need to be able to this with a query.
This query will select last description from before the event:
SELECT * FROM (
SELECT tabA.id, tabA.event_date, tabB.description,
ROW_NUMBER() OVER(PARTITION BY tabB.id ORDER BY tabB.event_date DESC) rn
FROM Table_A tabA
LEFT JOIN Table_B tabB ON tabA.id = tabB.id AND tabB.event_date <= tabA.event_date
) WHERE rn = 1
If I understand well your need, this could be a way:
select a.id, description
from tableA A
left join
(select id,
description,
event_date from_date,
lead(event_date) over (partition by id order by event_date) -1 as to_date
from tableB
) B
on (A.id = B.id and a.event_date between b.from_date and b.to_date)
The idea here is to evaluate, for each row in tableB the range of dates for which that row, and its description, is valid; given this, a simple join should do the job.
You can left join tables like:
select a.ID , b1.DESCRIPTION
from TABLE_A a
left join TABLE_B b1 on a.ID = b1.id and a.EVENT_DATE > b1.EVENT_DATE
left join TABLE_B b2 on a.ID = b2.id and b1.EVENT_DATE < b2.EVENT_DATE and a.EVENT_DATE > b2.EVENT_DATE
where b1.id is null or b2.EVENT_DATE is null;
I need help with my SQL Query I have Two tables that i need to join using a LEFT OUTER JOIN, then i need to create a database view over that particular view. If i run a query on the join to look for name A i need to get that A's latest brand "AP".
Table 1
ID name address
-----------------------
1 A ATL
2 B ATL
TABLE 2
ID PER_ID brand DATEE
--------------------------------------------
1 1 MS 5/19/17:1:00pm
2 1 XB 5/19/17:1:05pm
3 1 AP 5/19/17:2:00pm
4 2 RO 5/19/17:3:00pm
5 2 WE 5/19/17:4:00pm
I tried query a which returns correct result but i get problem 1 when i try to build the database view on top of the join. I tried query b but when i query my view in oracle sql developer i still get all the results but not the latest.
query a:
SELECT * from table_1
left outer join table_2 on table_1.ID = Table_2.PER_ID
AND table_2.DATE = (SELECT MAX(DATE) from table_2 z where z.PER_ID = table_2.PER_ID)
Problem 1
Error report -
ORA-01799: a column may not be outer-joined to a subquery
01799. 00000 - "a column may not be outer-joined to a subquery"
*Cause: <expression>(+) <relop> (<subquery>) is not allowed.
*Action: Either remove the (+) or make a view out of the subquery.
In V6 and before, the (+) was just ignored in this case.
Query 2:
SELECT * from table_1
left outer join(SELECT PER_ID,brand, max(DATEE) from table_2 group by brand,PER_ID) t2 on table_1.ID = t2.PER_ID
Use row_number():
select t1.id, t1.name, t1.address, t2.id as t2_id, t2.brand, t2.datee
from table_1 t1 left outer join
(select t2.*,
row_number() over (partition by per_id order by date desc) as seqnum
from table_2 t2
) t2
on t1.ID = t2.PER_ID and t2.seqnum = 1;
When defining a view, you should be in the habit of listing the columns explicitly.
These are the two tables. I want to select created time of TABLE1 for type = 'PENDINGTIMESTAMP' and type = 'DISTRIBUTEDTIMESTAMP' for TABLE2ID.
TABLE1
+------+--------+--------------------+-------------------+
|ID |TABLE2ID|TYPE |CREATED |
+------+--------+--------------------+-------------------+
|156174|849118 |PENDINGTIMESTAMP |2016-09-09 03:33:11|
|156175|849118 |DISTRIBUTEDTIMESTAMP|2016-09-09 03:33:11|
|156176|849118 |PROCESSTIME |2016-09-09 03:33:11|
|156177|849119 |DISTRIBUTEDTIMESTAMP|2016-09-09 03:33:11|
|156178|849119 |PROCESSTIME |2016-09-09 03:33:11|
+------+--------+--------------------+-------------------+
TABLE2
+------+-------------------+
|ID |CREATED |
+------+-------------------+
|849118|2016-09-09 05:00:00|
|849119|2016-09-09 06:00:00|
+------+-------------------+
If any of the entry not exist in TABLE1 for TABLE2ID then i want select created time of TABLE2.CREATED where TABLE2.ID
Final Result would be
+--------+-------------------+-------------------+
|TABLE2ID|TIME1 |TIME2 |
+--------+-------------------+-------------------+
|849118 |2016-09-09 03:33:11|2016-09-09 03:33:01|
|849119 |2016-09-09 06:00:00|2016-09-09 03:33:01|
+--------+-------------------+-------------------+
For Highlighted entry -> Entry not exist in TABLE1 and created timestamp taken from TABLE2
TIME1 in the second row should be taken from TABLE2
I tried somethink like below. It is doing cartesian product and return two many rows
select
table2.id table2id,
case when t2.logtype = 'PENDINGTIMESTAMP' then t2.created else table2.created end as time1,
case when t1.logtype = 'NEWTIMESTAMP' then t1.created else table2.created end as time2
from
table2,
table1 t1,
table1 t2
where
table2.id(+) = t1.table2id
and table2.id(+) = t2.table2id
i assume now, that table2 contains every possible table2id.
so I would create 2 outer joins from table2 to table1, one for pending and one for distributed timestamps.
finally, on selecting we can use the NVL function to use the created timestamp as fallback value.
SELECT m.id AS table2id,
NVL(p.created, m.created) AS time1,
NVL(d.created, m.created) AS time2
FROM table2 m
LEFT OUTER JOIN table1 p ON (p.table2id = m.id AND p.type = 'PENDINGTIMESTAMP')
LEFT OUTER JOIN table1 d ON (d.table2id = m.id AND d.type = 'DISTRIBUTEDTIMESTAMP')
or with Oracle outer join syntax (I'm not sure if the IS NULL is really necessary to compensate missing rows):
SELECT m.id AS table2id,
NVL(p.created, m.created) AS time1,
NVL(d.created, m.created) AS time2
FROM table2 m,
table1 p,
table1 d
WHERE m.id = p.table2id(+)
AND p.type(+) = 'PENDINGTIMESTAMP'
AND m.id = d.table2id(+)
AND d.type(+) = 'DISTRIBUTEDTIMESTAMP'
please note: I do not have a Oracle System to test the statement at hand, and I haven't used Oracle SQL syntax for about 3 years now. So please excuse, if there are syntactical errors.
But I hope, you get the idea.
I want to use DISTINCT in my hive query.So query looks like
Insert overwrite table tablename select distinct a.id AS ID , a.id AS SID from a left join b on a.id = b.id;
So in above query I want to insert same value for two different column.With DISTINCT query doesn't work ,otherwise it works.
I have two tables
Table A has columns id|name|age.
Table B has columns id|name|age.
Sample Records from table A
1|xavi |23
2|christine|24
3|faisal |25
5|jude |27
Sample Records from table B
1|xavi |23
2|christine|22
3|faisal |23
4|ram |25
If id values from table A matches in table B than take records from table A only.
Also take records which are present in table A only
Also take records which are present in table B only
So my result should be
1|xavi |23
2|christine|24
3|faisal |25
4|ram |25
5|jude |27
You can simply use union operator to get unique values from both tables. Operator UNION will remove repeated values.
SELECT * FROM tableA AS t1
UNION
SELECT * FROM tableB AS t2
You have a precedence problem here. Take all the records from table A and then the extra records from table B:
select *
from A
union all
select *
from B
where B.id not in (select A.id from A);
You can also express this with a full outer join (assuming id is not duplicated in either table):
select coalesce(A.id, B.id) as id,
coalesce(A.name, B.name) as name,
coalesce(A.age, B.age) as age
from A full outer join
B
on A.id = B.id;
In this case, the coalesce() gives priority to the values in A.
select distinct * FROM
(
select ID, NAME, AGE from TableA
UNION ALL
select ID, NAME, AGE from TableB
) TableAB
Some things to consider --> Unless you're updating specific tables and the records are the same, it will not matter which table you're viewing the records from (because they're the same...).
If you want to see which table the records are deriving from, let me know and i'll show you how to do that as well... but the query is more complex and i don't really think it's required for the purpose described above. let me know if this helps... thanks, Brian
If the tables has relation you need:
Select DISTINCT *
from tableA a
Inner Join tableB b
On a.id = b.id
If not:
You have to use UNION and after using DISTINCT.
DISTINCT will not permit repeat rows.