Complex SQL Join - database

I am fairly new to SQL joins, but I have a tricky issue here. I have tried to resolve this on my own, and searched as well, but unsuccessful.
I have two primary SQL tables
CustProfile
ClientID || ClientName
CustTransaction
CorpID || DivID || DeptID
I need to display my output as follows:
`CorpID` `CorpIDClientName` `DivID` `DivIDName` `DeptID` `DeptIDName`
CustTransaction.CorpID join on CustProfile.ClientID to get `CorpIDClientName`
CustTransaction.DivID join on CustProfile.ClientID to get `DivIDName`
CustTransaction.DeptID join on CustProfile.ClientID to get `DeptIDName`
I hope someone can provide the join query. Thanks in advance

try this one:
SELECT a.CorpID,
b.ClientName AS CorpIDClientName,
a.DivID,
c.ClientName AS DivIDName,
a.DeptID,
d.ClientName AS DeptIDName
FROM CustTransaction a
INNER JOIN CustProfile b
on a.CorpID = b.ClientID
INNER JOIN CustProfile c
on a.DivID = c.ClientID
INNER JOIN CustProfile d
on a.DeptID = d.ClientID

Am I understanding correctly? You have Corporations, Divisions, and Departments all stored within the CustProfile table together.
So you are only joining the 2 different tables, but you need to join those 2 tables 3 separate times to get each of the different types of customer (Corp or Div or Dept)
If that's the case, what you need to do is alias the table that you are including multiple times so you can join it as if it were 3 separate tables, one for corps, one for divisions, and one for departments.
I'm not sure if the syntax would be the same in MSSQL, but for most SQL databases your join query would look something like this:
SELECT corps.ClientID CorpID, corps.ClientName CorpIDClientName,
divs.ClientID DivID, divs.ClientName DivIDName,
depts.ClientID DeptID, depts.ClientName DeptIDName
FROM CustProfile corps, CustProfile divs, CustProfile depts, CustTransaction t
WHERE t.CorpID = corps.ClientID
AND t.DivID = divs.ClientID
AND t.DeptID = depts.ClientID
That should, I think, more or less do what you want...

Related

How can I get 3 tables INNER JOIN in MS SQL Server

From the specialist table, retrieve the first name, last name and contact number for the people that provide care to penguins from the species table.
There are 3 tables: tbl_specialist, tbl_species, tbl_care
I need help trying to INNER JOIN the tables to display First, Last, And Contact for penguins.
SELECT specialist_fname, specialist_lname, specialist_contact
FROM ((tbl_specialist
INNER JOIN tbl_species ON species_care = tbl_species.species_care)
INNER JOIN tbl_care ON care_id = tbl_care.care_id)
WHERE species_name = 'penguin'
;
It's a bit difficult without seeing the exact schema of the tables, but your syntax for the subquery is a bit off and you need to alias columns that are found in multiple tables in a JOIN statment. Try rewriting your SQL like this:
SELECT spl.specialist_fname, spl.specialist_lname, spl.specialist_contact
FROM tbl_specialist spl
INNER JOIN tbl_species s
ON spl.species_care = s.species_care
INNER JOIN tbl_care c
ON s.care_id = c.care_id
WHERE s.species_name = 'penguin'
I'm obviously inferring which tables certain columns come from in the join, but hopefully you get the idea.
I figured it out thank you.
SELECT specialist_fname, specialist_lname, specialist_contact
FROM ((tbl_specialist
INNER JOIN tbl_care ON tbl_care.care_specialist = tbl_specialist.specialist_id)
INNER JOIN tbl_species ON tbl_species.species_care= tbl_care.care_id)
WHERE species_name = 'penguin'
;

Joining multiple tables yields duplicates

In order to retrieve all Projects for a UserId, or all in case the user is admin, I want to join multiple tables. I'm using the statment in a TableAdapter query for MSSQL.
SELECT P.ID, P.CountryID, P.ProjectYear, P.Name, P.Objective, P.StartDate, P.EndDate, P.BaseCampaign, P.ManagerID, P.IsClosed, P.OrganisationUnitID, P.QualitativeZiele, P.QuantitativeZiele,
P.Herausforderungen, P.Learnings, P.ObjectiveQuantitativ, P.Remarks, P.ProjectOverallID, C.Name AS CountryName, O.Name AS OEName, R.RoleName
FROM wc_Projects AS P
INNER JOIN wc_OrganisationUnit AS O ON P.OrganisationUnitID = O.ID
INNER JOIN wc_Countries AS C ON P.CountryID = C.ID
INNER JOIN aspnet_Roles AS R ON C.ID = R.CountryID
INNER JOIN aspnet_UsersInRoles AS UR ON R.RoleId = UR.RoleId
WHERE (#ViewAll = 1) OR (UR.UserId = #UserId)
ORDER BY P.CountryID, P.OrganisationUnitID, P.ProjectYear DESC
In order to apply to the rather static approach for the table adapter, I start with the project.
Get all projects, resolve CountryName and OEName via FK's. Now look if you can find the role that is assoicated to the country. Then find the user that is attached to the role.
I know that this is a terrible query, but it's the only one somewhat applicable to the WebForms TableAdapter way to deal with it.
When I have a UserId that has one or multiple roles associated with countries it works. When a admin user, that has no roles with countries associated but ViewAll = 1 it breaks. I get constraint exceptions and the amount of results nearly tripple.
I tried rewriting the query, adding paranthesis and different joins. But none of it worked. How can I solve this?

Custom order for multiple joins in SQL Server

I am trying to write a query in SQL Server that replicates following figure:
I want the result of first left join (order_defect & ncdef) to be left join with third table (filter) and again the result of these three left join with last one (nsdic).
Each of these tables are huge, so I'm trying to find most efficient way to do it because i have limited space and I get "out of memory" error... any suggestion for an efficient query?
If I do:
Select *
from A
left join B on a.id = B.id
left join C on a.id = c.id
it's joining A and B first and then A and C...but I want the result of "A & B" to be join with "C".
Basically my question is how to use a result of one join, to join with another table.
Thank you
select
c.id
,c.colum1
,c.colum2
,c.colum3
,c.colum4
,t3.colum1
from
(
select
t1.id as id
,t1.colum1 as colum1
,t1.colum2 as colum2
,t2.column1 as colum3
,t2.colum2 as colum4
from table1 t1
left join table2 t2
on t1.id = t2.id
) as c
left join table3 t3
on c.id = t3.id
It's dificult to help you without the tables design and fields|columns, keys, ...
But I'll considerate:
1 - Primary keys fields, and how to relation the tables
2 - How to add left joins with "filters", or how to reduce the number of results
3 - Evaluate if it'll be better to use Sub-querys
Plus: Try the query with TOP 100 <--- to make test.
And remember: sometimes it's imposible to optimizate querys because of the hardware limits, like the RAM, in those case you have to show the data in sections.

Optimize joins from multiple tables

How can I optimize Performance of the below mentioned query when the table structure is as shown in the pic below
Pic Showing The Table Structure
select CounterID, OutletTitle, CounterTitle
from(
select OutletID, Text as OutletTitle
from Outlets as q1
inner join
TranslationTexts as tt
on q1.TitleID=tt.TranslationID
where tt.Locale='ar-SA' and q1.CompanyID=311 and q1.OutletID=8 --Locale & CompanyID & OutletID
) as O
inner join
(
select CounterID, Text as CounterTitle, OutletID
from Counters as q1
inner join
TranslationTexts as tt
on q1.TitleID=tt.TranslationID
where tt.Locale='ar-SA' and q1.OutletID=8 --Locale & OutletID
) as C
on O.OutletID=C.OutletID
You should try this request :
SELECT CounterID, tou.Text as OutletTitle, tco.Text as CounterTitle
FROM Counters as co
INNER JOIN Outlets as ou ON co.OutletID = ou.OutletID
INNER JOIN TranslationTexts as tco on co.TitleID=tco.TranslationID
INNER JOIN TranslationTexts as tou on ou.TitleID=tou.TranslationID
WHERE co.CompanyID=311 and co.OutletID=8 AND tco.Locale='ar-SA' and tou.Locale='ar-SA'
To have much better performance, you could add some indexes on the 3 tables.
This is a different approach. I cannot say about improvement in performance because that depends on a lot of other things, but I believe it is an equivalent version and an easier one to read.
SELECT
C.CounterID
, tt.Text AS OutletTitle
, tt.Text AS CounterTitle
FROM
Outlets AS q1
INNER JOIN TranslationTexts AS tt ON q1.TitleID=tt.TranslationID
INNER JOIN Counters C ON c.OutletID=q1.OutletID
INNER JOIN TranslationTexts AS tt2 ON tt2.TranslationID=tt.TranslationID AND tt2.Locale=tt.Locale
WHERE
tt.Locale='ar-SA' and q1.CompanyID=311 and q1.OutletID=8;
The question is what you want to optimize.. readability (and maintainability) and/or performance ?
Most people have their own 'style' when writing queries. I prefer the one below, but to the server it will probably look the same and most likely the system will have the exact same amount of 'work' to get the data even though it 'looks' different to us humans. I'd suggest to google around a bit and learn how to interpret a Query Plan.
SELECT q2.CounterID,
tt1.Text as OutletTitle,
tt2.Text as CounterTitle
FROM Outlets as q1
INNER JOIN Counters as q2
ON q2.OutletID = q1.OutletID
INNER JOIN TranslationTexts as tt1
ON tt1.TranslationID = q1.TitleID
AND tt1.Locale = 'ar-SA'
INNER JOIN TranslationTexts as tt2
ON tt2.TranslationID = q2.TitleID
AND tt2.Locale = 'ar-SA'
WHERE q1.CompanyID = 311
AND q1.OutletID = 8
On of the things I notice is that you pass both CompanyID and OutletID as filters for the Outlets table. Since OutletID is the primary key of that table I wonder if you really need the filter on CompanyID. At best it will eliminate the record because it's the wrong company, but somehow I'm under the impression that you already know the right CompanyID.
As for performance, I'd advice these indexes
CREATE INDEX idx_Locale ON TranslationTexts (Locale, Translation_id)
CREATE INDEX idx_CompanyID ON Outlets (CompanyID) INCLUDE (TitleID, OutletID)
Most likely you even can make that index on Local a UNIQUE index making it work even better.

How do I build a query that crosses multiple tables?

Here are my tables:
CUSTOMER
Cust_ID (PK)
Name
ORDERS
Order_ID (PK)
Cust_ID (FK)
ORDER_LINE
Order_ID (pk)
Part_ID (FK)
PART
Part_ID (PK)
Part_Description
Now I want to list the customer details, the part number and the description of the parts that each customer ordered.
How do i do this?
Thanks.
You should use "JOIN" using the FK, but from what I see you don't have a foreign key between "ORDERS" and "ORDER_LINE". Are you sure you're not missing something from the table definition, ie: ORDER_LINE should maybe have the ORDER_ID as a FK ?
Hope this helps
You can try something like
SELECT c.*,
p.*
FROM CUSTOMER c INNER JOIN
ORDERS o ON c.Cust_ID = o.Cust_ID INNER JOIN
ORDER_LINE ol ON o.Order_ID = ol.Order_Number INNER JOIN
PART p ON ol.Part_Number = p.Part_Number
Have a look at
Join (SQL)
An SQL join clause combines records from two or more tables in a
database.
SQL Joins
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.
And for some graphic examples
JOIN Basics
What you need is a simple straightforward JOIN like so:
SELECT
c.Cust_ID,
c.Name,
l.Part_Number,
l.Part_Description
FROM CUSTOMER c
INNER JOIN ORDERS o ON c.Cust_ID = o.Cust_ID
INNER JOIN ORDER_LINE ol ON o.OrdeR_ID = ol.Order_Number
INNER JOIN PART l ON ol.Part_Number = l.Part_Number
You want an SQL "join", such as:
SELECT c.Name, ol.Part_Number, p.Part_Description
FROM Customer AS c
JOIN Orders AS o ON c.Cust_ID = o.Cust_ID
JOIN Order_Line AS ol ON o.Order_ID = ol.Order_Number
JOIN Part AS p ON ol.Part_Number = p.Part_Number
Be aware that without a WHERE clause, this query will return all all parts in all orders for all customers, which will really hammer the network and perform poorly on anything but a tiny database:
WHERE (c.Cust_ID = MyCustomerID)
MySQL join syntax
SQL Server join syntax

Resources