How can I join three tables in MS Access SQL? - sql

I have a simple table model with 3 tables but I am not able to join them in the way I need it.
Table: TOPIC
ID TITLE
1 Talk1
2 Talk2
3 Talk3
4 Talk4
Table: SPEAKER
ID NAME
20 Speaker20
21 Speaker21
22 Speaker22
23 Speaker23
Table: CONNECTOR
ID_TOPIC ID_SPEAKER
1 21
2 23
2 22
2 21
4 20
4 22
In Table CONNECTOR the Topics are getting assigned to speakers.
One Topic can be assigned to different speakers.
There can also be topics in the TOPIC table which are not assigned yet, like in this example topic 3.
What I need is an SQL which give me as result all topics from the TOPICS table with the assigned speakers with name but I also want the topics in the result list which are not assigned through the CONNECTOR table.
How should the join look like to get this result?

I did an example in Access and got this:
As you can see, the query lists all topics, even if there is no speaker assigned. The SQL code of my query is this:
SELECT TOPICS.Title, SPEAKER.SpeakerName
FROM SPEAKER RIGHT JOIN (CONNECTOR RIGHT JOIN TOPICS ON CONNECTOR.ID_TOPIC = TOPICS.Id) ON SPEAKER.ID = CONNECTOR.ID_SPEAKER;
Hope this helps
UPDATE: Please, note that in table SPEAKERS, I've used as fieldname SpeakerName instead of Name because Name it's a reserved word, and it can create some troubles using it.

Look for
SELECT TOPIC.TITLE, SPEAKER.NAME
FROM ( CONNECTOR
INNER JOIN TOPIC ON TOPIC.ID = CONNECTOR.ID_TOPIC)
INNER JOIN SPEAKER ON CONNECTOR.ID_SPEAKER = SPEAKER.ID
UNION ALL
SELECT NULL, SPEAKER.NAME
FROM SPEAKER
LEFT JOIN CONNECTOR ON CONNECTOR.ID_SPEAKER = SPEAKER.ID
WHERE CONNECTOR.ID_TOPIC Is Null
UNION ALL
SELECT TOPIC.TITLE, NULL
FROM TOPIC
LEFT JOIN CONNECTOR ON TOPIC.ID = CONNECTOR.ID_TOPIC
WHERE CONNECTOR.ID_TOPIC Is Null;

Related

Trying to display id of table 1 as it relates to table 3

I have three tables: exfillocation, phishkit, snapshot. We need to be able to query exfillocation.filename and print the related snapshot.id, which requires traversing the phishkit table.
exfillocation.phishkit_id is related to phishkit.id as a foreign key.
Table exfillocation schema:
id exfil_location phishkit_id
== ========= ============
1 ['open.txt'] 7442
2 ['bot.txt'] 9931
phishkit.snapshot_id is related to snapshot.id as a foreign key.
Phishkit schema:
id snapshot_id md5
=== ============ =====
7442 1492 f4a3954e39b90c02f4a3954e39b90c02
9931 1661 e048f240ad0845b50abe8df9124ce3fb
Snapshot schema:
id asn url
=== ====== =============
1661 123 badwebsite.malicious.com
1492 31 haxx0rs.hacking.com
I've tried reading postgresql's four different JOIN methods as well as the UNION method, but I don't seem to get the snapshot_id column returned.
I tried something awkward this this:
SELECT exfil_location, found_in_file, phishkit_id
FROM public.lookup_exfillocation
FULL OUTER JOIN public.lookup_phishkit
ON public.lookup_exfillocation.phishkit_id = public.lookup_phishkit.id
FULL OUTER JOIN public.lookup_snapshot
ON public.lookup_phishkit.snapshot_id = public.lookup_snapshot.id WHERE exfil_location::text NOT LIKE ('__script.txt__') ORDER BY phishkit_id;
I expected to see the related lookup_snapshot.id and the related lookup_phishkit.id, which neither showed.
I accidentally found the solution. It came down to what columns I was SELECTing. Using a * showed all columns in the JOIN statements. Then I picked from the columns needed. The query looks like:
FROM public.lookup_exfillocation
FULL OUTER JOIN public.lookup_phishkit
ON public.lookup_exfillocation.phishkit_id = public.lookup_phishkit.id
FULL OUTER JOIN public.lookup_snapshot
ON public.lookup_phishkit.snapshot_id = public.lookup_snapshot.id WHERE exfil_location::text NOT LIKE ('__script.txt__') ORDER BY phishkit_id;```

Add columns to SQL query output

I have searched this site and others, and I am unable to find a clear answer, so here I am. In the below query, I will get an output with a single column for the county. What I would like to do can only be described in Excel parlance as transpose the counties so each county for a brand family is in its own column. I have played around with using pivot, but unfortunately do not fully grasp what would be required. This is not my first query, but I am relatively new to SQL scripting, so please ask any clarification questions and I will do my best to answer.
Some of the brand families have 10 counties and some have 20, so some of the columns would be blank. This is for an in-house DB, not the SO DB, running on SQL Server 2008R2, FWIW.
The script is:
select distinct b.reckey as BrandFamilyKey, b.recname as BrandFamilyName,
g.recname as County
from territories as t
left join dbo.TerritoryBrandFamilies as tbf on tbf.TerritoryNid = t.TerritoryNid
left join Customers as c on c.TerritoryNid = t.TerritoryNid
left join GeographicAreas as g on g.GeoAreaNid = c.GeoAreaNid
left join brandfamilies as b on b.brandfamilynid = tbf.brandfamilynid
where t.activeflag = 1 AND C.GeoAreaNid IS NOT NULL and b.activeflag = 1
order by b.RecName,g.recname
the output would look like
brand family 1 county 1
brand family 1 county 2
brand family 1 county 3
What I would like to see is:
brand family 1 county 1 county 2 county 3

SQL Join correct? Pulling more than I want

I have a system that is storing people applying for jobs. They are in the warehouse. When they apply for a job I create a record for them in the jobTracking table. That is simple. The issue is when someone applies for more then one position they get more then one record clearly in jobTracking. My issue is the ability to make a query to add people to a job internally based on a where clause. Let's say I want to add people to jobID=56 where their degree = "MD" and they haven't already applied. The list of people that appear post query will contain MDs who have already applied for 56 IF they have another record for another job. Who can I tell the query to ignore that applicantID in all records if one is a match? Tables are below. Query is also below that gives incorrect records. applicantID=10 will appear in my query below because he also has a record for job 46.
SELECT applicantWarehouse.first
, applicantWarehouse.last
, applicantWarehouse.title
, applicantWarehouse.ID
, jobTracking.applicantID
, jobTracking.jobID
FROM jobTracking INNER JOIN applicantWarehouse ON jobTracking.applicantID = applicantWarehouse.ID
WHERE Degree="MD"
AND jobTracking.jobID !=56
applicantWarehouse table
ID | First | Last | Degree
job table
jobID | jobTitle
jobTracking table
ID | applicantID | jobID
1 10 56
2 10 46
In your example you want to pull all people who have a degree md AND have not yet applied to jobID of 56. If that is what you need you can do this using not exists.
SELECT applicantWarehouse.first
, applicantWarehouse.last
, applicantWarehouse.title
, applicantWarehouse.ID
, jobTracking.applicantID
, jobTracking.jobID
FROM jobTracking INNER JOIN applicantWarehouse ON jobTracking.applicantID = applicantWarehouse.ID
WHERE Degree="MD"
AND NOT EXISTS (
SELECT 1
FROM jobTracking j
WHERE j.jobID = 56
AND j.applicantID = applicantWarehouse.ID )

Hibernate criteria left join with query

I have two classes Apartment and AdditionalSpace representing tables as below.
Apartment table
ID AREA SOLD
---- ------ ----
1 100 1
2 200 0
AdditionalSpace table
ID AREA APARTMENTID
---- ------ -----------
10 10 1
11 10 1
12 10 1
20 20 2
21 20 2
As you can see Apartment's table has a one-to-many relation with AdditionalSpace table, i.e. Apartment.ID=AdditionalSpace.APARTMENTID.
Question:- How to retrieve total area of a sold apartment including its additional space area.
The SQL which I have used so far to retrieve similar result is :-
select sum(apt.area + ads.adsarea) from apartment apt left outer join (select sum(area) as adsarea, apartmentid from additionalspace group by apartmentid) ads on ads.apartmentid=apt.id where apt.sold=1
I am struggling to find a way in order to implement the above scenario via criteria instead of SQL/HQL. Please suggest. Thanks.
I don't think this is possible in criteria. The closest I can see is to simply get the size of the apartment and the sum of the additional areas as two columns in your result, like this:
Criteria criteria = session.createCriteria(Apartment.class,"a");
criteria.createAlias("additionalSpaces", "ads");
criteria.setProjection(Projections.projectionList()
.add(Projections.property("area"))
.add(Projections.groupProperty("a.id"))
.add(Projections.sum("ads.area")));
Alternatively, if you still want to use Hibernate but are happy to write it in HQL, you can do the following:
select ads.apartment.id,max(a.area)+sum(ads.area)
from Apartment a
join a.additionalSpaces ads
group by ads.apartment.id
This works because HQL allows you to write the + to add together the two projections, but I don't know that an analogous method exists on the projections api.

Exclude entire row based on based on values from another query

I am using MS Access and I have a rather complex situation.
I have Respondents who are linked to varying numbers of different Companies via 2 connecting tables. I want to be able to create a list of distinct customers which excludes any customer associated with Company X.
Here is a pic of the relationships that are involved with the query.
And here is an example of what I'm trying to achieve.
RespondentRef | Respondent Name
8 Joe Bloggs
.
RespondentRef | GroupRef
8 2
.
GroupRef | CompanyRef
2 10
.
CompanyRef | CompanyName
10 Ball of String
I want a query where I enter in 'Ball of String' for the company name, and then it produces a list of all the Respondents (taken from Tbl_Respondent) which completely excludes Respondent 8 (as he is linked to CompanyName: Ball of String).
Tbl_Respondent
RespondentRef | Respondent Name
... ...
7 Bob Carlyle
9 Anton Boyle
I have tried many combinations of subqueries with <> and NOT EXISTS and NOT IN and nothing seems to work. I suspect the way these tables are linked may have something to do with it.
Any help you could offer would be very much appreciated. If you have any questions let me know. (I have made best efforts, but please accept my apologies for any formatting conventions or etiquette faux-pas I may have committed.)
Thank you very much.
EDIT:
My formatted version of Frazz's code is still turning resulting in a syntax error. Any help would be appreciated.
SELECT *
FROM Tbl_Respondent
WHERE RespondentRef NOT IN (
SELECT tbl_Group_Details_Respondents.RespondentRef
FROM tbl_Group_Details_Respondents
JOIN tbl_Group_Details ON tbl_Group_Details.GroupReference = tbl_Group_Details_Respondents.GroupReference
JOIN tbl_Company_Details ON tbl_Company_Details.CompanyReference = tbl_Group_Details.CompanyReference
WHERE tbl_Company_Details.CompanyName = "Ball of String"
)
This should do what you need:
SELECT *
FROM Tbl_Respondent
WHERE RespondentRef NOT IN (
SELECT gdr.RespondentRef
FROM Tbl_Group_Details_Respondent gdr
JOIN Tbl_Group_Details gd ON gd.GroupRef=gdr.GroupRef
JOIN Tbl_Company_Details cd ON cd.CompanyRef=gd.CompanyRef
WHERE cd.CompanyName='Ball of String'
)