How to join two tables first then join to another table - sql

I have a DB2 database and I have to join three tables. I would like to join first two tables and after joining firs two tables, I would like to join the joined table to another third table. I tried using left join but couldn't find a result as I expected. I tried the following:
select AFJKAR as "ELR_Elig_Redirect_SchdID",
AFEZAM as "Priority",
AFTSAS as "ELC_Status",
AFT7CE as "ELC_From_Date",
AFT8CE as "ELC_Thru_Date",
AFTTAS as "ELC_Redirect_Action",
AFJLAR as "GPI_List",
AIZAHA as "GPI_List_ID",
AILUIG as "GPI_Number",
AICXHG as "GPI_From_Date",
AICYHG as "GPI_Thru_Date",
SUEFC4 as "GPI_ID",
SUB4T3 as "Drug_Name"
from CLMPRDFIL.RCELCP as RCE
left join CLMPRDFIL.RCGP2P as RCG on RCE.AFJLAR = RCG.AIZAHA
left join CLMPRDFIL.RCGPIP as RCGP on RCG.AIZAHA = RCGP.SUEFC4;
Basically, I would like to join RCE and RCGP2P tables first. After joining this, I would like to join it by RCGPIP.

Use a corresponding optimization profile / guideline for this.
Optimization profiles and guidelines.
You may specify the desired join order there, if you believe, that you may achieve better performance with particular join order.
Note, that you should try to collect statistics on these tables first to make the Db2 optimizer use correct join order. For example, try to create a statistical view on first 2 tables using their join keys and collect statistics on it. Look at the access plan of your original query afterwards to check, if you get desired join order.

Related

Need Input | SQL Dynamic Query

Have a requirement where I need to build a dynamic query based on user input and send the count of records from result set.
So there are 6 tables which I needs to make a join Inner for sure and rest table join will be based on user input and this should be performance oriented.
Here is the requirement
select count(A.A1) from table A
INNER JOIN table B on B.B1=A.A1
INNER JOIN table B on C.C1=B.B1
INNER JOIN table D on D.D1=C.C1
INNER JOIN table E on E.E1=D.D1
INNER JOIN table F on F.F1=E.E1
Now if user select some value in UI , then have to execute query as
select count(A.A1) from table A
INNER JOIN table B on B.B1=A.A1
INNER JOIN table B on C.C1=B.B1
INNER JOIN table D on D.D1=C.C1
INNER JOIN table E on E.E1=D.D1
INNER JOIN table F on F.F1=E.E1
INNER JOIN table B on G.G1=F.F1
Where G.Name like '%Germany%'
User can send 1- 5 choices and have to build the query and accordingly and send the result set
So if I add all the joins first and then add where clause as per the choice , then query will be easy and serve the purpose, but if user did not select any query then I am creating unnecessary join for the user choices.
So which will be better way to write having all the joins in advance and then filtering it or on demand join and with filters using dynamic query.
Could be great if someone can provide valuable inputs.
When SQL Server executes a query, there is a first step which is planning the query, i.e. deciding an strategy to get the query result.
If you use "inner joins" you're making it compulsory to include all the tables, becasuse "inner join" means that there must be matching rows on both tables of the join, so the query planner can't dicard any tables.
However, if you change the inner joins by left outer joins, it's not compulsory that there are matching rows on both sides of the join, so the query planner can decide if it includes or not the tables on the right. So, if you use left outer joins, and you don't select, or filter, or do any operation on fields on the right side of the joins, the query planner can discard then when executing the query. That's the easiest way to get rid of your concerns.
On the other hand, if you want to control what tables to inclued or not to include, and create a custom query for each case, you can use several techniques:
making a graph that includes the definition of the table relations, and using some graph manipulation library that allows you to get the necessary tables from the graph.I did this one, but is quite hard to achieve if you don't have experience with graps.
using Entity Framework. You must build a simple model including all the tables. And then, to run each query, you can programmatically build the query in LINQ, and EF will take care to generate and execute the SQL query for you.

How to make my query more efficient?

I am running a query in an Oracle SQL environment using Toad where I build a table by joining 16 different tables and I am running out of temp tablespace and was hoping I could get some advice on how to make my query more efficient. I don't have a background in this so I am not sure if the best way is to use intermediary tables or change the order of my joins.
There are two main tables, Header and Detail, the header has 26 million rows, the detail has 175 million rows. I use an inner join with these tables which will result in 175 million rows. The other 14 tables are smaller description tables that I join using left joins. Three of those tables are 350k rows and less, the other 11 are under 1,000 rows. My current pseudo code is as follows:
create table END_TABLE as
select *
from Detail
inner join Header
left join description_table_1
left join description_table_2
left join description_table_3
left join description_table_4
left join description_table_5
left join description_table_6
left join description_table_7
left join description_table_8
left join description_table_9
left join description_table_10
left join description_table_11
left join description_table_12
left join description_table_13
left join description_table_14;
Since I am starting with my detail table and then joining the header is that less efficient than if I did it the other way around? I assumed since it was an inner join it wouldn't matter but like I said before I am not very knowledgeable on making queries more efficient.
My idea is to create a separate table joining the header and detail together and then create a final table where I join the smaller detail tables. Would this help? Would changing my join order help?
You are joining a table with 175 million rows against another table with 26 million rows using with no indices and no where clause.
You need indices. Without them, you're just shuffling around the deck chairs on the titanic.
Indices most likely will not help:
When you joining two tables entirely, Oracle most likely will do FULL TABLE SCAN of both tables, use HASH JOIN, and will not consider using indices.
You can try to partition Header and Detail tables and then join one partition at a time in the loop and insert results into END_TABLE table.
In my experience on Oracle 11g, when I was dealing with many joins of large tables, I found it often sped things up dramatically to use intermediate tables with fewer joins in each step (in one case what took 7 hours in one step took ~20 minutes in multiple steps). Probably I would join Detail and Header into one table, then left join this intermediate table against 1-3 description tables at a time, then start combining those further intermediate tables. You say you don't have indexes: I would expect indexes to speed the joins even if you aren't excluding any data in where constraints. Maybe you can't have indexes on the primary tables but you may be able to for the intermediate tables in case you go this path. Keep in mind that you need to think about whether you're maintaining one transaction throughout the series of queries in case the data are changing.
if your maximum amount of data is about 100% of data in the table (and based on your description it is) then you don't need indexes -FTS would work just fine.
I am not a big fan of ANSI SQL and prefer to use "right tool for the right task" - and using Oracle SQL syntax and NOT ANSI, but it seems that you are not specifying columns for joins. From my recollection you don't need columns only when you use NATURAL JOIN - WIKI. All other cases of JOIN need definition of which columns are participants.
Columns specifications also relevant for LEFT JOIN (LEFT OUTER JOIN) - again

SQL Server: select over several tables / conditions

Okay, I'm relatively new to the more advanced uses of SQL Server.
I have several tables that I need to gather informations from, and several of these tables links to other tables where I need a specific information. As a result, I just want one row with all the information, preferential named with aliases.
For example:
Tab_Transcoders:
ID, VideoCamID, InputStreamID, OutputStreamID.
where InputStream links to another table where I need the row of the matching ID, where in this row are other ID's (e.g. StreamType_ID that belongs to a third table containing ID_StreamType and Description etc.)
Same with OutputStreamID, same with VideoCamID.
In the end, I need a row containing for example:
ID, VideoCamID, InputStreamID, InputStreamType, InputStreamTypeDesc,
OutputStreamID, OutputStreamType, OutputStreamDesc, VideoCamID, etc. etc. etc.
It is important for me that I can set aliases, as for example InputStreamID & OutputStreamID links to the same table where all my Streams are listed (with IP's, Descs..)
I can accomplish this with doing like 100 SELECTS & SUBSELECTS, but I don't think that's an appropriate way.
I read some informations about things like CURSOR, UNION, FETCH, JOIN etc. etc.. but I don't know which one I have to use for my purpose.
eli
I think you want something like the following....
Select
t.ID,
t.VideoCamID,
i.InputStreamID,
is.StreamType as InputStreamType,
is.StreamDesc as InputStreamDesc,
o.OutputStreamID,
os.StreamType as OutputStreamType,
os.StreamDesc as OutputStreamDesc,
v.VideoCamID
from
Tab_Transcoders t
inner join InputStreams i on i.InputStreamID=t.InputStreamId
inner join Streams is on is.StreamId=i.StreamId
inner join OutputStreams o on o.OutputStreamId=t.OutputStreamId
inner join Streams os on os.StreamID=o.StreamId
inner join VideoCams v on v.VideoCamId=t.VideoCamID
If there is a defined relationship between your tables, then Use Join.
e.g Customer Order
Order will have customer Id
Select Order.ID,Order.Quantity, Order.CustomerId, Customer.FullName, Customer.Address
From Orders Order
Join
Customer
On
Order.CustomerId = Customer.CustomerId
First start by getting data from two tables using the join and then if it works as per your requirement, add another required table in the join.
Read about SQl JOINS.. It is fairly simple.
I will recommend reading you some of the articles around CTE aka Common Table Expression.
Refer http://msdn.microsoft.com/en-us/library/ms190766%28v=sql.105%29.aspx.
Apart from this never use subqueries. Try to use inner join / any other join if possible.

When to use SQL natural join instead of join .. on?

I'm studying SQL for a database exam and the way I've seen SQL is they way it looks on this page:
http://en.wikipedia.org/wiki/Star_schema
IE join written the way Join <table name> On <table attribute> and then the join condition for the selection. My course book and my exercises given to me from the academic institution however, use only natural join in their examples. So when is it right to use natural join? Should natural join be used if the query can also be written using JOIN .. ON ?
Thanks for any answer or comment
A natural join will find columns with the same name in both tables and add one column in the result for each pair found. The inner join lets you specify the comparison you want to make using any column.
IMO, the JOIN ON syntax is much more readable and maintainable than the natural join syntax. Natural joins is a leftover of some old standards, and I try to avoid it like the plague.
A natural join will find columns with the same name in both tables and add one column in the result for each pair found. The inner join lets you specify the comparison you want to make using any column.
The JOIN keyword is used in an SQL statement to query data from two or more tables, based on a relationship between certain columns in these tables.
Different Joins
* JOIN: Return rows when there is at least one match in both tables
* LEFT JOIN: Return all rows from the left table, even if there are no matches in the right table
* RIGHT JOIN: Return all rows from the right table, even if there are no matches in the left table
* FULL JOIN: Return rows when there is a match in one of the tables
INNER JOIN
http://www.w3schools.com/sql/sql_join_inner.asp
FULL JOIN
http://www.w3schools.com/sql/sql_join_full.asp
A natural join is said to be an abomination because it does not allow qualifying key columns, which makes it confusing. Because you never know which "common" columns are being used to join two tables simply by looking at the sql statement.
A NATURAL JOIN matches on any shared column names between the tables, whereas an INNER JOIN only matches on the given ON condition.
The joins often interchangeable and usually produce the same results. However, there are some important considerations to make:
If a NATURAL JOIN finds no matching columns, it returns the cross
product. This could produce disastrous results if the schema is
modified. On the other hand, an INNER JOIN will return a 'column does
not exist' error. This is much more fault tolerant.
An INNER JOIN self-documents with its ON clause, resulting in a
clearer query that describes the table schema to the reader.
An INNER JOIN results in a maintainable and reusable query in
which the column names can be swapped in and out with changes in the
use case or table schema.
The programmer can notice column name mis-matches (e.g. item_ID vs itemID) sooner if they are forced to define the ON predicate.
Otherwise, a NATURAL JOIN is still a good choice for a quick, ad-hoc query.

Possible to combine two tables without losing all data by using JOINS

I have a table as below and I would like to know if I can still join them together, without losing existing data from both tables when they are combined by referencing JOIN methods.
Table details - VIEW Table
SELECT
r.domainid,
r.DomainStart,
r.Domain_End,
r.ddid,
r.confid,
r.pdbcode,
r.chainid,
d.pdbcode AS "CATH_PDBCODE",
d.cathbegin AS "CATH_BEGIN",
d.cathend AS "CATH_END"
FROM dyndom_domain_table r
JOIN cath_domains d ON d.pdbcode::character(4) = r.pdbcode
ORDER BY confid ASC;
As you can see, dyndom_domain_table is a VIEW Table that I have created to make it easier for me to use JOIN clauses with the other table that has the same pdbcode.
So far it just returns all of the data that matches with the PDB Code. What I would like to do is return all of the data that both matches and doesn't match each other's PDB Code.
Is there a rule in which I can apply it to? Or is it not possible?
I believe you want a FULL OUTER JOIN rather than just a JOIN (which is, by default, an INNER JOIN). In a FULL OUTER JOIN, every row in each table will correspond to some row in the result table; rows from one table that don't match the other will be extended with NULLs to fill the missing column.
So FULL OUTER JOIN instead of just JOIN, and that should do you.
I think you're asking for a left join, but I'm not sure.
SELECT
r.domainid,
r.DomainStart,
r.Domain_End,
r.ddid,
r.confid,
r.pdbcode,
r.chainid,
d.pdbcode AS "CATH_PDBCODE",
d.cathbegin AS "CATH_BEGIN",
d.cathend AS "CATH_END"
FROM dyndom_domain_table r
LEFT JOIN cath_domains d ON d.pdbcode::character(4) = r.pdbcode
ORDER BY confid ASC;