SQL multiple table Syntax - sql

I have a table with a bunch of specific details and some detail codes for bridges. There are other separate tables with the descriptions for the various codes. For instance a table for Curb type, table for sidewalk type, another for joint type and so on.
I would like to create a query that gives me all the details per Bridge, but with the Code descriptions from the other tables for the fields that supply the code. the result would give me the ID, dimensions, curb code description, Sidewalk code description and so on.
Any help to point me in the right direction is sincerely appreciated.

Something like
SELECT b.Id, b.something, b.CurbTypeID, c.CurbDescription, b.SidewalkTypeID, s.SidewalkDescription
FROM Bridges b
INNER JOIN Curb c on c.CurbID = b.CurbTypeId
LEFT OUTER JOIN Sidewalk s on s.SidewalkID = b.SidewalkTypeID
The difference between INNER JOIN and LEFT OUTER JOIN being that you use a LEFT OUTER JOIN if you're not confident that all your SidewalkTypeID values are actually listed in the Sidewalk table, or if SidewalkTypeID is blank sometimes.

Related

SQL query wrong index when where on join

I have a query with joins that is not using the index that would be the best match and I am looking for help to correct this.
I have the following query:
select
equipment.name,purchaselines.description,contacts.name,vendors.accountNumber
from purchaselines
left join vendors on vendors.id = purchaselines.vendorId
left join contacts on contacts.id = vendors.contactId
left join equipment on equipment.id = purchaselines.equipmentId
where contacts.id = 12345
The table purchaselines has an index on the column vendorId, which is the proper index to use. When the query is run, I know the value of contacts.id which is joined to vendors.contactId which is joined to purchaselines.vendorId.
What is the proper way to run this query? Currently, no index is used on the table purchaselines.
If you are intending to query a specific contact, I would put THAT first since that is the primary basis. Additionally, you had left-joins to the other tables (vendors, contacts, equipment). So by having a WHERE clause to the CONTACTS table forces the equation to become an INNER JOIN, thus REQUIRING.
That said, I would try to rewrite the query as (also using aliases for simplified readability of longer table names)
select
equipment.name,
purchaselines.description,
contacts.name,
vendors.accountNumber
from
contacts c
join vendors v
on c.id = v.contactid
join purchaselines pl
on v.id = pl.vendorid
join equipment e
on pl.equipmentid = e.id
where
c.id = 12345
Also notice the indentation of the JOINs helps readability (IMO) to see how/where each table gets to the next in a more hierarchical manner. They are all regular inner JOIN context.
So, the customer ID will be the first / fastest, then to vendors by that contact ID which should optimize the join to that. Then, I would expect the purchase lines to have an index on vendorid optimizing that. And finally, the equipment table on ITs PK.
FEEDBACK Basic JOIN clarification.
JOIN is just the explicit statement of how two tables are related. By listing them left-side and right-side and the join condition showing on what relationship is between them is all.
Now, in your data example, each table is subsequently nested under the one prior. It is quite common though that one table may link to multiple other tables. For example an employee. A customer could have an ethnicity ID linking to an ethnicity lookup table, but also, a job position id also linking to a job position lookup table. That might look something like
select
e.name,
eth.ethnicity,
jp.jobPosition
from
employee e
join ethnicitiy eth
on e.ethnicityid = eth.id
join jobPosition jp
on e.jobPositionID = jp.id
Notice here that both ethnicity and jobPosition are at the same hierarchical level to the employee table scenario. If, for example, you wanted to further apply conditions that you only wanted certain types of employees, you can just add your logical additional conditions directly at the location of the join such as
join jobPosition jp
on e.jobPositionID = jp.id
AND jp.jobPosition = 'Manager'
This would get you a list of only those employees who are managers. You do not need to explictily add a WHERE condition if you already include it directly at the JOIN/ON criteria. This helps keeping the table-specific criteria at the join if you ever find yourself needing LEFT JOINs.

Getting repeats of output, possibly doing a join wrong?

I'm having an issue where I'm getting some incorrect values in my output. I am binding the below highlighted table column with the circled column down the bottom. The service_id on the highlighted column is what is unique, but I need to bind the booking_id to retrieve the info (if that makes sense. What I end up getting is the top table where I get repeats, or the price is wrong. I should be getting only 5 lines in the top table.
Here's my code. I suspect I might be doing the join wrong?
SELECT bad.agent as Agents,
dog.SUPPLIER as SUPPLIER,
bad.status as TheStatus,
country.analysis_master1 as Country,
ftb.booking_actual_retail as BookingActualRetail,
ftb.Booking_Actual_Cost as BookingCost,
ftb.Booking_Actual_Retail_inc as BookingRetailINC,
fts.Service_Id,
fts.Service_Actual_Retail_inc as ServiceActualCostInc,
Product.SERVICE,
Product.SL_STATUS as SLSTATUS,
cat.name as Product2,
bad.LAST_SERVICE_DATE as Servicedate,
bad.LW_DATE as LWDATE,
ftb.Entered_Date as DATEENTERED,
ftb.Booking_Pax as PEOPLE,
ftb.Booking_Children as KIDS,
bad.TRAVELDATE as TRAVELDATE,
bad.FULL_REFERENCE
from BHD bad
inner join FTB on bad.FULL_REFERENCE = ftb.booking_reference
inner join FTS on FTB.Booking_Id = fts.Booking_Id
inner join DRM Country on bad.agent = country.code
inner join BSL Product on bad.BHD_ID = Product.BHD_ID
inner join SRV cat on Product.SERVICE = cat.CODE
inner join OPT dog on Product.OPT_ID = dog.OPT_ID
where bad.STATUS = 'IV' AND bad.FULL_REFERENCE = 'LTIT129488'
UPDATE:
Ok, so it looks like this join here causes the multiple outputs:
inner join FTS on FTB.Booking_Id = fts.Booking_Id
I have included the two tables, their headers, and sample data
You have somewhere put the join for the service or supplier in the wrong way.. Please check this line again.
inner join SRV cat on Product.SERVICE = cat.CODE
UPDATED SOLUTION :
As per your updated screenshots, I found the issue...
you have joined like this.
inner join FTB on bad.FULL_REFERENCE = ftb.booking_reference
In this join, your one table has single record against booking reference while another have multiple records against booking refrence. Thats why you are getting the multiple records in the output.
Remove this join and your problem will be solved. If you really want the data from this table then you can select in other way like using outer apply etc.

SQL INNER JOIN without linked column

I have an UltraGrid displaying customer information in it. The way the database is set up, there are 2 tables. Customers and Customer_Addresses. I need to be able to display all of the columns from Customers as well as Town and Region from Customer_Addresses, but I'm under the impression that I'd need Town and Region columns in the Customer table to be able to do this? I've never used an INNER JOIN before so I'm not sure if this is true or not, so can anybody give me pointers on how to do this, or if I need the matching columns or not?
Does it even require an INNER JOIN, or is there an alternative way to do this?
Below are the design views of both of the tables - Is it possible to display Add4 and Add5 from Customer_Addresses with all of Customers?
As long as you have another key column you can use to link the tables (ex. ID_Column), it is better that you use LEFT JOIN.
Example:
SELECT c.col1, ... , c.colN, a.town, a.region FROM Customers c
LEFT JOIN Customer_Addresses a ON a.ID_Column = c.ID_Column
In order to clarify how JOIN types work, look at this picture:
In our case, using a LEFT JOIN will take all information from the Customers table, along with any found matching (on ID) information from Customer_Addresses table.
First of all you need some column in common in two tables, all what you have to do is:
CREATE TABLE all_things
AS
SELECT * (or columns that you want to have in the new table)
FROM Costumers AS a1
INNER JOIN Customer_Addresses AS a2 ON a1.column_in_common = a2.column_in_common
The point is what kind of join do you want.
If you can continue the process without having information in table Costumers or in table Customer_Addresses maybe you need OUTER JOIN or other kind of JOIN.

SQL Update - Using Multiple Table Joins

Wondering if anyone can point me in the right direction please.
I Have 3 tables...
Table A -
Code, Cost1, Cost2, Cost3
Table B -
Code, ID
Table C -
ID, Price
Basically I need to update the Price Field on Table C with (Cost1+Cost2+Cost3)
from Table A.
There is no direct link between the 2 tables, but A is linked to B via Code and B is linked to C via ID.
I can write a query to display Price and the Total Cost but can't get my head around how to do the Update.
Any pointers would be extremely welcome
Thanks
Andrew
UPDATE TC
SET Price=(TA.Cost1+TA.Cost2+TA.Cost3)
FROM TableA TA
INNER JOIN TableB TB ON TA.Code=TB.Code
INNER JOIN TableC TC ON TC.ID=TB.ID
I prefer writing my more complicated joins out first and then simply updating the alias. As you can see in the example, you could comment out the top two lines and simply put in a SELECT TC.ID,TA.Cost1+TA.Cost2+TA.Cost3 and see exactly what would change.

join a same table with different tables

I am wondering if anyone can help me, I have these tables:
tbl_search_history(id,fld_user_id,fld_username_fld_make_id,fld_model_id,fld_year_id,fld_category_id)
The fld_make is the name of the make:
tbl_make(id,fld_make)
The fld_model is the name of that model
tbl_model(id,fld_model)
The fld_year is the name of that year
tbl_year(id, fld_year)
The fld_category is the name of that category
tbl_category(id,fld_category)
Now I need to show a table in my page in which I need to have this fields: make, model, year, and category. I also want to know how can I have the make, model, year, and category names (instead of just the reference numbers from the tbl_search_history) in my page? Would you please give me a piece of code and a brief explanation?
Thanks in advance!
Your question is a bit unclear, but it sounds like a homework problem.
I will give you some pseudocode and references.
First off I would do some reading on JOINS.
If you are asking to get Column Names, see this SO question
I believe what you want to do is join your tables like so:
SELECT table1.desired_field, table2.desired_field2, table3.desired_field3
FROM table1
JOIN table2 ON table1.table2_id = table2.id
JOIN table3 ON table1.table3_id = table3.id
and so on.
SELECT
tbl_model.fld_make,
tbl_make.fld_model,
tbl_year.fld_year,
tbl_category.fld_category
FROM
tbl_search_history
INNER JOIN tbl_make ON tbl_search_history.fld_make_id = tbl_make.id
INNER JOIN tbl_model ON tbl_search_history.fld_model_id = tbl_model.id
INNER JOIN tbl_year ON tbl_search_history.fld_year_id = tbl_year.id
INNER JOIN tbl_category ON tbl_search_history.fld_category_id = tbl_category.id
Assuming that the search history table is the table that links all these other tables together. Also assuming that all of these tables have linked values (ie non-null id's in tbl_search_history) otherwise you'd need to use an OUTER JOIN.
What you want to do is to join with the make, model, year, and category tables using the ids you have in the tbl_search_history.
Something of this sort will give you want you want :
SELECT * FROM `tbl_search_history`
INNER JOIN `tbl_make`
ON tbl_search_history.fld_make_id = tbl_make.id
#keep going for model, year, and category tables using their respective ids.
Hope this helps!