Doing a join in SQL Server - sql

I'm trying to achieve a join where the select statement has multiple column that will reference the same name in a particular table, example:
SELECT
sh.shift_number,
sh.workplace_num,
wp.workplace_name,
sh.workplace_num2,
sh.workplace_num3
FROM shifts AS sh
INNER JOIN workplace AS wk
ON wp.workplace_num = wk.workplace_num
My problem is I'm able to get the name of the first workplace, how do i get the same for workplace2 or workplace three
Shift_number | workplace_Num | workplace_name | workplace_Num2 | workplace_Num3
4 | 2 | Teller | 3 | 4
As you can see o Wk_placename(Teller) displays the name of wk_placeNum(2) I'd like to be able to show the names of Wk_placeNum2 and Wk_placeNum3 they all take the workplace name from the joined workplace table!!
I'm restricted from uploading a picture, hopefully the illustration paints a picture!!

You have to join multiple times to the workplace table. Note that as you did not specified whether the fields workplace_num2 and workplace_num3 are nullable, I assumed these are so used LEFT JOIN. You should use INNER JOIN if these are not nullable:
SELECT
sh.shift_number,
sh.workplace_num,
wp.workplace_name,
sh.workplace_num2,
wp2.workplace_name as workplace_name2,
sh.workplace_num3
wp3.workplace_name as workplace_name3,
FROM shifts AS sh
INNER JOIN workplace AS wp
ON sh.workplace_num = wp.workplace_num
LEFT JOIN workplace AS wp2
ON sh.workplace_num2 = wp2.workplace_num
LEFT JOIN workplace AS wp3
ON sh.workplace_num3 = wp3.workplace_num

Try this:
SELECT
sh.shift_number,
sh.workplace_num,
wk.workplace_name,
wk2.workplace_name,
wk3.workplace_name
FROM shifts AS sh
INNER JOIN workplace AS wk
ON sh.workplace_num = wk.workplace_num
INNER JOIN workplace AS wk2
ON sh.workplace_num2 = wk2.workplace_num
INNER JOIN workplace AS wk3
ON sh.workplace_num3 = wk3.workplace_num

Related

SQL - Simple Pivot Table while using Join statements?

I'm trying to transpose my results from the following code which is joining multiple tables together. I know i need to use a PIVOT for this and it may be a simple fix, but i'm having huge difficultly getting the code to work. My code is as follows:
SELECT F.SetValue, D.Name FROM Device D
INNER JOIN Location L ON D.LocationId = L.LocationId
INNER JOIN Fitting F ON L.LocationId = F.LocationId
INNER JOIN LocationTypeFitting LTF ON F.LocationTypeFittingId = LTF.LocationTypeFittingId
WHERE D.DeviceName = 'Device 1' AND LTF.Name LIKE '%Television%';
which prints the following results:
SetValue | Name
===========================
1 | TV_Power
1 | TV_Volume
1 | TV_Source
I need to return the values as below:
TV_Power | TV_Volume | TV_Source
================================
1 | 1 | 1
I know i'll also need a GROUP BY statement, but the the joining of additional tables is making this particular query increasingly difficult. Any help would be very much appreciated.
I would do the following two things:
Wrap the whole query in a sub-query and apply the pivot syntax.
Add another column, such as DeviceName from the Device table (or some other table), so that you can differentiate the rows once the pivot has been executed (I assume there will be more than one row).
it also shows where the group by would go in the comments.
select post_pivot.*
from (
SELECT F.SetValue, D.Name, D.DeviceName FROM Device D
INNER JOIN Location L ON D.LocationId = L.LocationId
INNER JOIN Fitting F ON L.LocationId = F.LocationId
INNER JOIN LocationTypeFitting LTF ON F.LocationTypeFittingId = LTF.LocationTypeFittingId
WHERE D.DeviceName = 'Device 1' AND LTF.Name LIKE '%Television%'
--group by (if needed)
) as pre_pivot
pivot (max(pre_pivot.set_value) for pre_pivot.Name in ([TV_Power], [TV_Volume], [TV_Source])) as post_pivot
Hopefully this will be sufficient or will give you enough to go on.
SELECT 'DeviceType' as DeviceTYpe,* FROM
(
SELECT D.Name, F.SetValue FROM Device D
INNER JOIN Location L ON D.LocationId = L.LocationId
INNER JOIN Fitting F ON L.LocationId = F.LocationId
INNER JOIN LocationTypeFitting LTF ON F.LocationTypeFittingId = LTF.LocationTypeFittingId
WHERE D.DeviceName = 'Device 1' AND LTF.Name LIKE '%Television%'
) AS SourceTable
PIVOT
(
MAX(SetValue)
FOR Name in ([TV_Power], [TV_Volume], [TV_Source])
) As PivotTable

Left Join On And clause not supported

I've looked into various posts (this one, that one and this other one) and thought I got the answer.
After a LEFT JOIN I may add an ON [condition] AND [other condition] (I've also tried WHERE). But computer says no. Access keeps saying the join expression is not supported.
Consider the student_records table below:
STUDENTCODE | SEMESTERINDEX
12345 | 20112
12345 | 20113
12345 | 20121
67890 | 0
67890 | 20111
67890 | 20112
I want to find the minimum SEMESTERINDEX for each student from my students table, that's above 20001. (Records below may be erroneous and the 0 and 1 SEMESTERINDEX is used for transferred credits.)
I'm using access so there are VBA functions inside the SQL. There's several more tables I'm joining too, I'm quoting the whole query.
SELECT students.STUDENTCODE, prefixes.PREFIXNAMEENG,
students.STUDENTNAMEENG, students.STUDENTSURNAMEENG, levels.level_name, programs.PROGRAMNAMEENG, calendars.calendar_load,
MAX(student_records.SEMESTERINDEX) AS latest_semester, MIN(student_records.SEMESTERINDEX) AS intake_semester,
FROM student_records LEFT JOIN (
(
(
(
(students LEFT JOIN prefixes ON students.PREFIXID = prefixes.PREFIXID)
LEFT JOIN levels ON students.LEVELID = levels.level_id)
LEFT JOIN programs ON students.PROGRAMID = programs.PROGRAMID)
LEFT JOIN calendar_conversion ON students.SCHEDULEGROUPID = calendar_conversion.schedule_id)
LEFT JOIN calendars ON calendar_conversion.calendar_id = calendars.calendar_id) ON student_records.STUDENTCODE = students.STUDENTCODE AND student_records.SEMESTERINDEX> 2001
GROUP BY students.STUDENTCODE, prefixes.PREFIXNAMEENG, students.STUDENTNAMEENG, students.STUDENTSURNAMEENG, levels.level_name, programs.PROGRAMNAMEENG, calendars.calendar_load;
So did I misplace the AND student_records.SEMESTERINDEX > 2001?
oh my save me from these parenthesis and crazy indenting.
Here is how you do it. All the parenthesis don't matter in SQL
SELECT
students.STUDENTCODE,
prefixes.PREFIXNAMEENG,
students.STUDENTNAMEENG,
students.STUDENTSURNAMEENG,
levels.level_name,
programs.PROGRAMNAMEENG,
calendars.calendar_load,
minmax.latest_semester,
minmax.intake_semester,
FROM student_records
LEFT JOIN (
SELECT
studentcode,
MAX(student_records.SEMESTERINDEX) AS latest_semester,
MIN(student_records.SEMESTERINDEX) AS intake_semester
FROM students
WHERE students.STUDENTCODE > 2001
GROUP BY studentcode
) as MinMax ON student_records.STUDENTCODE = minmax.STUDENTCODE
LEFT JOIN students ON student_records.STUDENTCODE = students.STUDENTCODE
LEFT JOIN prefixes ON students.PREFIXID = prefixes.PREFIXID
LEFT JOIN levels ON students.LEVELID = levels.level_id
LEFT JOIN programs ON students.PROGRAMID = programs.PROGRAMID
LEFT JOIN calendar_conversion ON students.SCHEDULEGROUPID = calendar_conversion.schedule_id
LEFT JOIN calendars ON calendar_conversion.calendar_id = calendars.calendar_id
This is called a sub-query in sql it allows you to perform your grouping on a sub-set and then join that back to the rest of the data.
I think you went wrong thinking there was something about the join that needed a filter -- in fact it is the data that you were joining to that needed to be filtered.

complex inner join sql

You are my last hope. I've spend all day but I haven't decided how to create this query.
This is my current database diagram
Every storage have 1 roster
Every roster consist from chief and worker. Information about them is on stuff table .
What I try to do? Get all storage(square adress), worker_name, worker_surname, chief_name, chief_surname.
What I have so far
select storage_address,
storage_square,
stuffs.stuff_name as chiefSurname,
stuffs.stuff_surname as chiefName from storages
inner join storageRoster on storageRoster.storageRoster_id=storages.storage_roster_id
inner join Chiefs on storageRoster.chief_id = Chiefs.chief_id
inner join stuffs on Chiefs.chief_stuff_id = stuffs.stuff_id
But in this query I can only get chiefs on every storage. Help please. I am desperate.
You need to join the stuff table twice, once for worker and once for chief:
select storage_address,
storage_square,
cs.stuff_name as chiefSurname,
cs.stuff_surname as chiefName,
ws.stuff_name as workerSurname,
ws.stuff_surname as workerName
from storages
inner join storageRoster on storageRoster.storageRoster_id=storages.storage_roster_id
inner join Chiefs on storageRoster.chief_id = Chiefs.chief_id
inner join stuffs cs on Chiefs.chief_stuff_id = cs.stuff_id
inner join Workers on storageRoster.worker_id = Workers.chief_id
inner join ws cs on Workers.worker_stuff_id = ws.stuff_id

Joining 5 tables in Access 2010

So here's a challenge. I have a webpage that needs to show data from 5 different tables in a database. Here's the query:
'SELECT ORGANIZATIONS.ORG_NAME, ORG_SECTIONS.SectionName, ATTORNEYS.NAME, ATTORNEYS.LASTNAME, ATTORNEYS.EMAIL, ATTORNEYS.TEL, ATTY_TITLES.ATT_TITLE, FIRM_PRACTICE_GRPS.PRACTICE_GRP
FROM (ORGANIZATIONS INNER JOIN (Org_Sec_Atty INNER JOIN ATTORNEYS ON Org_Sec_Atty.Atty_ID = ATTORNEYS.ATTY_ID) ON ORGANIZATIONS.ID = Org_Sec_Atty.OrgID) INNER JOIN ORG_SECTIONS ON Org_Sec_Atty.SecID = ORG_SECTIONS.ID
WHERE ATTORNEYS.LASTNAME LIKE #LASTNAME;'
The 5 tables are Org_Sec_Atty, ORGANIZATIONS, ORG_SECTIONS, ATTORNEYS, ATTY_TITLES, and FIRM_PRACTICE_GRPS. First, I didn't come up with the table names, lol.
Second, ATTORNEYS is the table that has ATTY_ID, TITLE_ID, PRACTICE_GRP_ID, which is what I'm sure I need to join to FIRM_PRACTICE_GRPS and ATTY_TITLE, and then it needs to connect with the Org_Sec_Atty and ORG_SECTIONS table.
I already have a page where the three tables ATTORNEYS, Org_Sec_Atty, and ORG_SECTIONS are joined by the JOIN statement you see up there. I'm trying to figure out where the other INNER JOIN statements would go and in what order.
It seems like I need to replace "ATTORNEYS" in the "Org_Sec_Atty INNER JOIN ATTORNEYS" with the subordinate INNER JOIN statements, but, again, I'm not sure of the order. Is this possible?
You didn't specified foreign keys on last two tables. Change appropriately if necessary:
SELECT ORGANIZATIONS.ORG_NAME ,
ORG_SECTIONS.SectionName ,
ATTORNEYS.NAME ,
ATTORNEYS.LASTNAME ,
ATTORNEYS.EMAIL ,
ATTORNEYS.TEL ,
ATTY_TITLES.ATT_TITLE ,
FIRM_PRACTICE_GRPS.PRACTICE_GRP
FROM (((( ORGANIZATIONS
INNER JOIN Org_Sec_Atty ON ORGANIZATIONS.ID = Org_Sec_Atty.OrgID)
INNER JOIN ATTORNEYS ON Org_Sec_Atty.Atty_ID = ATTORNEYS.ATTY_ID)
INNER JOIN ORG_SECTIONS ON Org_Sec_Atty.SecID = ORG_SECTIONS.ID)
INNER JOIN ATTY_TITLES ON ORG_SECTIONS.ATTY_ID = ATTY_TITLES.ID)
INNER JOIN FIRM_PRACTICE_GRPS ON ATTY_TITLES.FIRM_ID = FIRM_PRACTICE_GRPS.ID
WHERE ATTORNEYS.LASTNAME LIKE #LASTNAME;

SQL joins "going up" two tables

I'm trying to create a moderately complex query with joins:
SELECT `history`.`id`,
`parts`.`type_id`,
`serialized_parts`.`serial`,
`history_actions`.`action`,
`history`.`date_added`
FROM `history_actions`, `history`
LEFT OUTER JOIN `parts` ON `parts`.`id` = `history`.`part_id`
LEFT OUTER JOIN `serialized_parts` ON `serialized_parts`.`parts_id` = `history`.`part_id`
WHERE `history_actions`.`id` = `history`.`action_id`
AND `history`.`unit_id` = '1'
ORDER BY `history`.`id` DESC
I'd like to replace `parts`.`type_id` in the SELECT statement with `part_list`.`name` where the relationship I need to enforce between the two tables is `part_list`.`id` = `parts`.`type_id`. Also I have to use joins because in some cases `history`.`part_id` may be NULL which obviously isn't a valid part id. How would I modify the query to do this?
Here is some sample date as requested:
history table:
(source: ianburris.com)
serialized_parts table:
(source: ianburris.com)
parts table:
(source: ianburris.com)
part_list table:
(source: ianburris.com)
And what I want to see is:
id name serial action date_added
4 Battery 567 added 2010-05-19 10:42:51
3 Antenna Board 345 added 2010-05-19 10:42:51
2 Main Board 123 added 2010-05-19 10:42:51
1 NULL NULL created 2010-05-19 10:42:51
This would at least be on the right track...
If you're looking to NOT show any parts with an invalid ID, simply change the LEFT JOINs to INNER JOINs (they will restrict NULL values)
SELECT `history`.`id`
, `parts`.`type_id`
, `part_list`.`name`
, `serialized_parts`.`serial`
, `history_actions`.`action`
, `history`.`date_added`
FROM `history_actions`
INNER JOIN `history` ON `history`.`action_id` = `history_actions`.`id`
LEFT JOIN `parts` ON `parts`.`id` = `history`.`part_id`
LEFT JOIN `serialized_parts` ON `serialized_parts`.`parts_id` = `history`.`part_id`
LEFT JOIN `part_list` ON `part_list`.`id` = `parts`.`type_id`
WHERE `history`.`unit_id` = '1'
ORDER BY `history`.`id` DESC
Boy, these backticks make my eyes hurt.
SELECT
h.id,
p.type_id,
pl.name,
sp.serial,
ha.action,
h.date_added
FROM
history h
INNER JOIN history_actions ha ON ha.id = h.action_id
LEFT JOIN parts p ON p.id = h.part_id
LEFT JOIN serialized_parts sp ON sp.parts_id = h.part_id
LEFT JOIN part_list pl ON pl.id = p.type_id
WHERE
h.unit_id = '1'
ORDER BY
history.id DESC