Joining Two Queries onto a Shared Table - sql

I have been struggling with the concept of combining results of two queries together via a join on a common table and I was hoping I could gain some assistance. The following is a rough guide to the tables:
dbo.Asset (not returned in the SELECT statement, used for joins only)
- dbo.Asset.AssetID
- dbo.Asset.CatalogueID
dbo.WorkOrder
- WorkOrderID
- AssetID
- WorkOrderNumber
dbo.WorkOrderSpare
- WorkOrderID
- WorkOrderSpareID
- WorkOrderSpareDescription
- ActualQuantity
- CreatedDateTime
dbo.Catalogue
- CatalogueID (PK)
- CatalogueNumber
- CatalogueDescription
- CatalogueGroupID
dbo.CatalogueGroup
- CatalogueGroupID
- CatalogueGroupNumber
First Query:
SELECT CatalogueGroup.CatalogueGroupName,
Catalogue.CatalogueNumber,
Catalogue.CatalogueDescription,
Catalogue.CatalogueID,
Asset.IsActive
FROM CatalogueGroup
INNER JOIN Catalogue
ON CatalogueGroup.CatalogueGroupID = Catalogue.CatalogueGroupID
INNER JOIN Asset
ON Catalogue.CatalogueID = Asset.CatalogueID
Second Query:
SELECT WorkOrder.WorkOrderNumber,
WorkOrderSpare.WorkOrderSpareDescription,
WorkOrderSpare.ActualQuantity,
WorkOrderSpare.CreatedDateTime
FROM WorkOrder
INNER JOIN WorkOrderSpare
ON WorkOrder.WorkOrderID = WorkOrderSpare.WorkOrderID
Now I can do the above easily enough in Access (WYSIWYG) by joining Asset/Catalogue/CatalogueGroup together and then joining Asset.AssetID onto WorkOrder.AssetID. I can't seem to get anything similar to work via raw code, I think I have my logic correct for the joins (INNER JOIN on the results of both) but then I am new to this.
Any assistance would be greatly appreciated, any pointers on where I can read further into problems like this would be great.
EDIT: This is what I was trying to use to no avail, I should also mention I am trying to do this in ms-sql, not Access (trying to move away from drag and drop):
SELECT CatalogueGroup.CatalogueGroupName,
Catalogue.CatalogueNumber,
Catalogue.CatalogueDescription,
Catalogue.CatalogueID,
Asset.IsActive,
WorkOrderSpare.WorkOrderSpareDescription,
WorkOrderSpare.ActualQuantity,
WorkOrderSpare.CreatedDateTime,
WorkOrder.WorkOrderNumber
FROM (((CatalogueGroup
INNER JOIN Catalogue
ON CatalogueGroup.CatalogueGroupID = Catalogue.CatalogueGroupID)
INNER JOIN Asset ON Catalogue.CatalogueID = Asset.CatalogueID)
INNER JOIN WorkOrderSpare
ON WorkOrder.WorkOrderID = WorkOrderSpare.WorkOrderID)
INNER JOIN WorkOrder ON Asset.AssetID = WorkOrder.AssetID

Think I see the issue. Assuming that the joins themselves are correct (ie your columns do relate to each other), the order of your joins is a little off - when you join WorkOrder to WorkOrderSpare, neither of those two tables relate back to any table you've identified up until that point in the query. Think of it as joining two tables separately from the chain of joins you have going so far - it's almost like doing two separate join queries. If you switch the last two it should work, that way WorkOrder will join to Asset (which you've already defined) and then you can join WorkOrderSpare to WorkOrder. I've also taken the liberty of removing parentheses on the joins, that's an Access thing.
SELECT CatalogueGroup.CatalogueGroupName,
Catalogue.CatalogueNumber,
Catalogue.CatalogueDescription,
Catalogue.CatalogueID,
Asset.IsActive,
WorkOrderSpare.WorkOrderSpareDescription,
WorkOrderSpare.ActualQuantity,
WorkOrderSpare.CreatedDateTime,
WorkOrder.WorkOrderNumber
FROM CatalogueGroup
INNER JOIN Catalogue ON CatalogueGroup.CatalogueGroupID = Catalogue.CatalogueGroupID
INNER JOIN Asset ON Catalogue.CatalogueID = Asset.CatalogueID
INNER JOIN WorkOrder ON Asset.AssetID = WorkOrder.AssetID
INNER JOIN WorkOrderSpare ON WorkOrder.WorkOrderID = WorkOrderSpare.WorkOrderID

I think you were close. As a slightly different approach to joining, try this:
SELECT CatalogueGroup.CatalogueGroupName,
Catalogue.CatalogueNumber,
Catalogue.CatalogueDescription,
Catalogue.CatalogueID,
Asset.IsActive,
WorkOrderSpare.WorkOrderSpareDescription,
WorkOrderSpare.ActualQuantity,
WorkOrderSpare.CreatedDateTime,
WorkOrder.WorkOrderNumber
FROM
CatalogueGroup, Catalogue, Asset, WorkOrder, WorkOrderSpare
WHERE CatalogueGroup.CatalogueGroupID = Catalogue.CatalogueGroupID
and Catalogue.CatalogueID = Asset.CatalogueID
and Asset.AssetID = WorkOrder.AssetID
and WorkOrder.WorkOrderID = WorkOrderSpare.WorkOrderID
It looks like it should work, but not having data, hard to know if simple joins all the way through is what you want. (It's a matter of personal preference whether to use the and clauses rather than the inner join syntax. While on style preferences, I like table aliases if supported, so FROM CatalogueGroup cg for example, so that you can refer to cg.CatalogueGroupID etc, rather than writing out the full table name every time.)

Ok. so the error that you noted in a comment
The multi-part identifier "WorkOrder.WorkOrderID" could not be bound
is usually when you have an alias for a table and instead of using alias in JOIN you use the table name or when you are using the wrong column name or table name.
Ideally in SQL server your query should look like this
SELECT
cg.CatalogueGroupName,
c.CatalogueNumber,
c.CatalogueDescription,
c.CatalogueID,
A.IsActive,
Wo.WorkOrderNumber,
WoS.WorkOrderSpareDescription,
WoS.ActualQuantity,
WoS.CreatedDateTime
FROM CatalogueGroup cg
INNER JOIN Catalogue c ON cg.CatalogueGroupID = c.CatalogueGroupID
INNER JOIN Asset A ON c.CatalogueID = A.CatalogueID
INNER JOIN WorkOrder Wo ON Wo.AssetID= A.AssetID
INNER JOIN WorkOrderSpare WoS ON Wo.WorkOrderID = WoS.WorkOrderID

Related

SQL SELECT Statement Using Three Tables

I am trying to write a SQL Select statement to port some data from a Sybase environment to a MongoDB environment and I'm just trying to figure out the correct syntax to involve three different tables.
Basically what I need to do is do an INNER JOIN on two tables, and then do a matching check against a 3rd table. The three table names are "ar_notes", "customer_service_xref" and "service_notes_details"
This is what I tried:
SELECT * FROM ar_notes arn
LEFT JOIN customer_service_xref csx ON arn.customer_service_xref_id = csx.id_number
WHERE arn.visit_date = service_notes_details.date_of_visit
This doesn't work. I get a correlation error.
What should the syntax look like when involving three tables like this?
You said you need an INNER JOIN among three tables but your query does a LEFT JOIN between two and tries another join in the WHERE clause without refering that table in the FROM clause.
To just fix your query:
SELECT *
FROM service_notes_details snd, ar_notes arn
INNER JOIN customer_service_xref csx ON arn.customer_service_xref_id = csx.id_number
WHERE arn.visit_date = snd.date_of_visit
This is what you should use in current SQL syntax:
SELECT *
FROM ar_notes arn
INNER JOIN customer_service_xref csx ON arn.customer_service_xref_id = csx.id_number
INNER JOIN service_notes_details ON arn.visit_date = service_notes_details.date_of_visit
To be clear, this will only return lines in ar_notes that have corresponding values in customer_service_xref (joining by customer_service_xref_id) and in service_notes_details(joining by visit_date). Your original query, using LEFT JOIN would return lines from ar_notes even if there was no matching customer_service_xref_id.

SQL Statement for Accessing Data from Multiple Tables

I have 7 Tables as per attached following Image.
I will either enter Engine Number or Chassis Number and it should show the respective tables information (these tables have only mentioned fields) so all fields can be shown as result.
I can use hard coded Engine Number or Chassis Number. Every time of execution of this Query, I will hard code the required Engine/Chassis Number and will get the result.
Can anybody please help me to write this query for me?
Click Here to See the Tables
This might be a starting point for your solution.
SELECT prod.EngineNo AS engNo, prod.ChassisNo, doral.doralNo [, table.column [AS name]]
FROM DOProductSpecsDetais AS prod
INNER JOIN DORAL AS doral
ON prod.DOProductSpecsDetailID = doral.DOProductSpecsID
INNER JOIN DOProductDetail AS prodDetail
ON prod.DOProductDetailID = prodDetail.DOProductDetailID
WHERE prod.ChassisNo = '<input>' OR prod.EngineNo='<input>'
Between the SELECT and the FROM Statement, you can select any column out of your JOIN.
You can cascade as many JOINs as you like...
Which DBMS are you going to use?
One suggestion: Try to simplify the names of your columns, if possible.
One more: If you just started to do Database things, it is always helpful to start a test environment and use a client tool.
You can write query something like this:
select * from
DoProductSpecsDetail tbl1 inner join Doral tbl2
on tbl1.DoProductSpecsDetailId = tbl2.DoProductSpecsId
inner join DoproductDetail tbl3
on tbl1.DoProductDetailId = tbl3.DoProductDetailId
inner join ProductColor tbl4
on tbl1.ProductColorId = tbl4.ProductColorId
inner join DoDetail tbl5
on tbl3.DeliveryOrderDetailId = tbl5.DeliveryOrderId
inner join ProductMain tbl6
on tbl3.ProductId = tbl6.ProductId
inner join BPMain tbl7
on tbl5.BusinessPartnerId = tbl7.BusinessPartnerId

SQL How to get columns from other tables based on other columns

I need to get values like
AdviserInit, AdviserSurname, MaterialName and Area using AdviserID, MaterialID and AreaCode from Chores Table as my reference.
I don't know what will be my approach in creating the query. This is what I've come up with so far:
SELECT Chores.ChoresID, Chores.ChoresDate, Materials.MaterialName,
Advisers.AdviserInit, Advisers.AdviserSurname, Area.Area,
Chores.StudentID
FROM Chores INNER JOIN Materials on Chores.MaterialID = Materials.MaterialID
INNER JOIN Advisers on Chores.AdviserID = Advisers.AdviserID
INNER JOIN Area on Chores.AreaCode = Area.AreaCode
Here's the screenshot of the relationships between the tables:
You can try this query, if you want to map all tables with main Chores Table,
SELECT Chores.ChoresID, Chores.ChoresDate, Materials.MaterialName,
Advisers.AdviserInit,Advisers.AdviserSurname, Area.Area,
Chores.StudentNo, Student.Forename
FROM (((Chores INNER JOIN Materials on Chores.MaterialID = Materials.MaterialID)
INNER JOIN Advisers on Chores.AdviserID = Advisers.AdviserID)
INNER JOIN Area on Chores.AreaCode = Area.AreaCode)
INNER JOIN Student on Student.StudentNo = Chores.StudentNo
The placement of the parentheses is important here. Basically, you need to have n - 2 left parentheses after the from clause and one right parenthesis before the start of each new join clause except for the first, where n is the number of tables being joined together.
The reason is that Access's join syntax supports joining only two tables at a time, so if you need to join more than two you need to enclose the extra ones in parentheses.

Group by in SQL Server giving wrong count

I have a query which works, goes like this:
Select
count(InsuranceOrderLine.AntallPotensiale) as potensiale,
COUNT(InsuranceOrderLine.AntallSolgt) as Solgt,
InsuranceProduct.Name,
InsuranceProductCategory.Name as Kategori
From
InsuranceOrderLine, InsuranceProduct, InsuranceProductCategory
where
InsuranceOrderLine.FKInsuranceProductId = InsuranceProduct.InsuranceProductID
and InsuranceProduct.FKInsuranceProductCategory = InsuranceProductCategory.InsuranceProductCategoryID
Group by
InsuranceProduct.name, InsuranceProductCategory.Name
This query over returns what I need, but when I try to add more table (InsuranceOrder) to be able to get the regardingUser column, then all the count values are way high.
Select
count(InsuranceOrderLine.AntallPotensiale) as Potensiale,
COUNT(InsuranceOrderLine.AntallSolgt) as Solgt,
InsuranceProduct.Name,
InsuranceProductCategory.Name as Kategori,
RegardingUser
From
InsuranceOrderLine, InsuranceProduct, InsuranceProductCategory, InsuranceSalesLead
where
InsuranceOrderLine.FKInsuranceProductId = InsuranceProduct.InsuranceProductID
and InsuranceProduct.FKInsuranceProductCategory = InsuranceProductCategory.InsuranceProductCategoryID
Group by
InsuranceProduct.name, InsuranceProductCategory.Name,RegardingUser
Thanks in advance
You're adding one more table to your FROM statement, but you don't specify any JOIN condition for that table - so your previous result set will do a FULL OUTER JOIN (cartesian product) with your new table! Of course you'll get duplication of data....
That's one of the reasons that I'm recommending never to use that old, legacy style JOIN - do not simply list a comma-separated bunch of tables in your FROM statement.
Always use the new ANSI standard JOIN syntax with INNER JOIN, LEFT OUTER JOIN and so on:
SELECT
count(iol.AntallPotensiale) as Potensiale,
COUNT(iol.AntallSolgt) as Solgt,
ip.Name,
ipc.Name as Kategori,
isl.RegardingUser
FROM
dbo.InsuranceOrderLine iol
INNER JOIN
dbo.InsuranceProduct ip ON iol.FKInsuranceProductId = ip.InsuranceProductID
INNER JOIN
dbo.InsuranceProductCategory ipc ON ip.FKInsuranceProductCategory = ipc.InsuranceProductCategoryID
INNER JOIN
dbo.InsuranceSalesLead isl ON ???????? -- JOIN condition missing here !!
When you do this, you first of all see right away that you're missing a JOIN condition here - how is this new table InsuranceSalesLead linked to any of the other tables already used in this SQL statement??
And secondly, your intent is much clearer, since the JOIN conditions linking the tables are where they belong - right with the JOIN - and don't clutter up your WHERE clauses ...
It looks like you added the table join which slightly multiplies count of rows - make sure, that you properly joining the table. And be careful with aggregate functions over several joined tables - joins very often lead to duplicates

Basic SQL join question. Can you help me improve my skillset?

Ok.. So I'm trying to improve my SQL skills and have a question. Here is a screen shot of the schema.
Schema http://img509.imageshack.us/img509/97/screenhunter02nov121946.gif
(http://img509.imageshack.us/img509/97/screenhunter02nov121946.gif)
Alright so I'm selecting a bunch of Report Bundles and other rows from a table you can see. I've got these two tables joining together correctly and displaying what should be returned. Now I need to add another field onto my result rows that states what type of report this is. How can I join up to the ReportGroupType table through the ReportBundleGroup table without getting a shwack of results?
Here is the query I am using so far.
SELECT *
FROM ReportBundleCustomerVisibility INNER JOIN ReportBundle
ON ReportBundleCustomerVisibility.ReportBundleID = ReportBundle.ID
WHERE ReportBundleCustomerVisibility.ReferenceCustomerID = 2303
Thanks again SO
SELECT *
FROM ReportBundleCustomerVisibility AS v
JOIN ReportBundle AS b ON b.ID = v.ReportBundleID
JOIN ReportBundleGroup AS g ON b.ID = g.ReportBundleID
JOIN ReportGroupTYpe AS t ON t.ID = g.ReportGroupTypeID
WHERE v.ReferenceCustomerID = 2303
It sounds like you just need another inner join to get the information you need. You can think about the second join as joining the result of the join with the ReportGroupType table. I added parenthesis to try to join the two sets the second INNER JOIN is operating on.
SELECT * FROM ((ReportBundleCustomerVisibility
INNER JOIN ReportBundle ON ReportBundleCustomerVisibility.ReportBundleID = ReportBundle.ID)
INNER JOIN ReportGroupType ON ReportBundleGroup.ReportGroupTypeID = ReportGroupType.ID)
WHERE ReportBundleCustomerVisibility.ReferenceCustomerID = 2303
I also highly suggest against using "SELECT *" in production code or any query you plan on reusing as the table schema can change and possibly effect reports and UI. Explicitly specify the columns instead.