How to join two tables using sub queries? - oracle-sqldeveloper

How to join two tables using sub queries in oracle sql server?
i tried it this way
select s.*,p.* from salary s
cross join (select p.* from pension p where p.sal=21);

I believe you need to name the subquery:
select s.*,p.* from salary s
cross join (select * from pension where sal=21) p

Related

Using UNNEST in a custom Postres Query in Google Data Studio

I have a table that has multiple values saved in an array in one column. (I know that this is not normalized/optimal database structure.) I'm trying to write a query that can create rows for each value in the array. The query below is working for me in Tableau but not Google Data Studio (I'm using a custom query with the PostgreSQL connector). Are there any limitations/different syntax requirements when using UNNEST in Data Studio?
SELECT
e.name as event_name,
e.date as event_date,
l.full_name as leader_name,
p.full_name as participant_name
FROM
(
SELECT
event_id,
user_id,
UNNEST(participants_ids)::INTEGER as participant_id
from event_reports
) r
LEFT JOIN events e ON r.event_id = e.id
LEFT JOIN users l ON r.user_id = l.id
LEFT JOIN users p ON r.participant_id = p.id
Your inner query should probably have a lateral join:
SELECT e.event_id,
e.user_id,
p.participant_id
FROM event_reports AS e
CROSS JOIN
LATERAL unnest(e.participants_ids) AS p(as participant_id)
With a lateral join, you can reference something from the left side of the join on the right side. The cross join combines each event_reports row with rach participant ID that belongs to that row.

query optimization how to reduce planning time and execution time in postgresql

query optimization how to reduce planning time and execution time in postgresql.
SQL Query :-
select s.id,state_name state, d.id no_districts,b.id no_blocks,v.id no_villages,district_name district,block_tehsil_name block,village_name village ,corr_vs,non_corr_vs,corr_gw,non_corr_gw,corr_sw,non_corr_sw
from ref_state s left join ref_district d on d.ref_state_id=s.id
left join ref_block_tehsil b on d.id=b.ref_district_id
left join ref_village v on v.ref_block_tehsil_id=b.id
left join (select ref_village_id ,coalesce(sum(tot_vs),0)-coalesce(sum(non_corr_vs),0) corr_vs,sum(non_corr_vs)non_corr_vs
from (select ref_village_id,count(vs.id)tot_vs,(select count(id) from mi_census_village_schedule_validation vsv where vsv.ref_village_id=vs.ref_village_id)non_corr_vs from mi_census_village_schedule vs group by ref_village_id )vs1 group by ref_village_id ) vs on vs.ref_village_id=v.id
left join(select ref_village_id ,coalesce(sum(tot_gw),0)- coalesce(sum(non_corr_gw),0) corr_gw,sum(non_corr_gw)non_corr_gw from (select ref_village_id,count(gws.id)tot_gw,(select count(id) from mi_census_ground_water_scheme_validation gwsv where gwsv.ref_village_id=gws.ref_village_id)non_corr_gw from mi_census_ground_water_scheme gws group by ref_village_id )gws1 group by ref_village_id ) gws on gws.ref_village_id=v.id
left join (select ref_village_id,coalesce(sum(tot_sw),0)- coalesce(sum(non_corr_sw),0) corr_sw,sum(non_corr_sw)non_corr_sw from(select ref_village_id,count(sws.id)tot_sw,(select count(id) from mi_census_surface_water_scheme_validation swsv where swsv.ref_village_id=sws.ref_village_id)non_corr_sw from mi_census_surface_water_scheme sws group by ref_village_id )sws1 group by ref_village_id ) sws on sws.ref_village_id=v.id
where s.id=30and d.id=21 and b.id=127 and v.id=632
there are several techniques that can help improve the performance of SQL queries under workspaces. Follow the SQL best practices to ensure query optimization like
proper indexes,so that SQL queries can cause minimal table scans
Avoid using functions in predicates.
Avoid using wildcard (%) at the beginning of a predicate.
Avoid unnecessary columns in SELECT clause.
Use inner join, instead of outer join if possible. -- You have used multiple left join in your above query which also impact your query.
DISTINCT and UNION should be used only if it is necessary.
use of order by clause when sorted result set is required.Be aware of the performance impact of adding the ORDER BY clause, as the database needs to sort the result set, resulting in one of the most expensive operations in SQL execution

Postgres: left join with order by and limit 1

I have the situation:
Table1 has a list of companies.
Table2 has a list of addresses.
Table3 is a N relationship of Table1 and Table2, with fields 'begin' and 'end'.
Because companies may move over time, a LEFT JOIN among them results in multiple records for each company.
begin and end fields are never NULL. The solution to find the latest address is use a ORDER BY being DESC, and to remove older addresses is a LIMIT 1.
That works fine if the query can bring only 1 company. But I need a query that brings all Table1 records, joined with their current Table2 addresses. Therefore, the removal of outdated data must be done (AFAIK) in LEFT JOIN's ON clause.
Any idea how I can build the clause to not create duplicated Table1 companies and bring latest address?
Use a dependent subquery with max() function in a join condition.
Something like in this example:
SELECT *
FROM companies c
LEFT JOIN relationship r
ON c.company_id = r.company_id
AND r."begin" = (
SELECT max("begin")
FROM relationship r1
WHERE c.company_id = r1.company_id
)
INNER JOIN addresses a
ON a.address_id = r.address_id
demo: http://sqlfiddle.com/#!15/f80c6/2
Since PostgreSQL 9.3 there is JOIN LATERAL (https://www.postgresql.org/docs/9.4/queries-table-expressions.html) that allows to make a sub-query to join, so it solves your issue in an elegant way:
SELECT * FROM companies c
JOIN LATERAL (
SELECT * FROM relationship r
WHERE c.company_id = r.company_id
ORDER BY r."begin" DESC LIMIT 1
) r ON TRUE
JOIN addresses a ON a.address_id = r.address_id
The disadvantage of this approach is the indexes of the tables inside LATERAL do not work outside.
I managed to solve it using Windows Function:
WITH ranked_relationship AS(
SELECT
*
,row_number() OVER (PARTITION BY fk_company ORDER BY dt_start DESC) as dt_last_addr
FROM relationship
)
SELECT
company.*
address.*,
dt_last_addr as dt_relationship
FROM
company
LEFT JOIN ranked_relationship as relationship
ON relationship.fk_company = company.pk_company AND dt_last_addr = 1
LEFT JOIN address ON address.pk_address = relationship.fk_address
row_number() creates an int counter for each record, inside each window based to fk_company. For each window, the record with latest date comes first with rank 1, then dt_last_addr = 1 makes sure the JOIN happens only once for each fk_company, with the record with latest address.
Window Functions are very powerful and few ppl use them, they avoid many complex joins and subqueries!

Crystal Reports: expressions in table joining

Is it possible to join tables in Crystal Records by using not simple and usual field A = field B but something more complex like:
select * from table1 inner join table2
on table1.A=2*table2.B
or
select * from table1 inner join table2
on ASCII(table1.A)=ASCII(table2.B)
Use a single Command instead of tables in the Database Expert. You will be able to use more-complex SQL.

How to select distinct-columns along with one nondistinct-column in DB2?

I need to perform distinct select on few columns out of which, one column is non-distinct. Can I specify which columns make up the distinct group in my SQL statement.
Currently I am doing this.
Select distinct a,b,c,d from TABLE_1 inner join TABLE_2 on TABLE_1.a = TABLE_2.a where TABLE_2.d IS NOT NULL;
The problem I have is I am getting 2 rows for the above SQL because column D holds different values. How can I form a distinct group of columns (a,b&c) ignoring column d, but have column d in my select clause as well?
FYI: I am using DB2
Thanks
Sandeep
SELECT a,b,c,MAX(d)
FROM table_1
INNER JOIN table_2 ON table_1.a = table_2.a
GROUP BY a,b,c
Well, your question, even with refinements, is still pretty general. So, you get a general answer.
Without knowing more about your table structure or your desired results, it may be impossible to give a meaningful answer, but here goes:
SELECT a, b, c, d
FROM table_1 as t1
JOIN table_2 as t2
ON t2.a = t1.a
AND t2.[some_timestamp_column] = (SELECT MAX(t3.[some_timestamp_column])
FROM table_2 as t3
WHERE t3.a = t2.a)
This assumes that table_1 is populated with single rows to retrieve, and that the one-to-many relationship between table_1 and table_2 is created because of different values of d, populated at unique [some_timestamp_column] times. If this is the case, it will get the most-recent table_2 record that matches to table_1.