Im trying to use join on in my sql to link between three tables but still have errors
when I'm trying to retrieve:
(Aminah’s lecturer and subject)
i did this but still have errors
SELECT c.SUBJECT1,c.SUBJECT2,c.SUBJECT3,l.NAME
FROM
STUDENT s
JOIN COURSE c
ON c.COURSE = s.COURES
JOIN LECTURER l
ON l.LECT_ID =c.LECT1 AND c.LECT2 AND c.LECT3
WHERE s.NAME = 'Aminah' AND c.SUBJECT1 = c.LECT1 AND c.SUBJECT2 = c.LECT2 AND c.SUBJECT3 = c.LECT3
also same thing when i am trying to show:
(Subject that teach by Ahmad)
i am a beginner andit is still hard to me with using (join on)
i hope some one help me
I think you want multiple joins, like this:
select c.subject1, c.subject2, c.subject3,
l1.name as name_1, l2.name as name_2, l2.name as name_2
from student s join
course c
on s.course = c.course left join
lecturer l1
on c.lect_1 = l1.lect_id left join
lecturer l2
on c.lect_2 = l2.lect_id left join
lecturer l3
on c.lect_3 = l3.lect_id
where s.name = 'Aminah';
You should also know that this is a really bad data model. It is suspicious whenever you have "arrays" (such as courses) that are spread across columns. These should actually be in separate rows to be better suited to SQL.
Related
The problem
I have to make a SQL (postgres) query, to show the names of players, whose teams participate in the "Primeira Liga" and the "Taça de Portugal". Also, include the names of players of "Académica" club and all of teams founded in the 1940s.
Image of Database design
I'm really stuck and can't figure out, how to connect all tables. Does anyone know how to solve the problem?
Thanks in advance.
Updated (10/01/2021):
** I had to change the names to match my DB, so everyone can understand.
(SELECT DISTINCT j.nome
FROM jogador as j
INNER JOIN equipa as E
ON E.id = j.equipa_id
INNER JOIN competicao_equipa as eq
ON E.id = eq.equipa_id
WHERE (eq.competicao_id = 1 OR eq.competicao_id = 3))
UNION
(SELECT j.nome
FROM jogador as j
where equipa_id = 1)
UNION
(SELECT j.nome
FROM jogador as j,equipa
where equipa.fundacao BETWEEN '01/01/1940' AND '31/12/1949')
I want to display all information of table program but it must based on other table (which is Line), I try to use join but it will show ALL information from ALL TABLE.
Can someone help me to create the query or just tell me what should i do.
TABLE LINE
------------
LineName
TABLE PACKAGE
-------------
PackageNo
PackageName
Line
TABLE FAMILY
------------
FamilyCode
FamilyName
TestQuant
TABLE PROGRAM
-------------
FamilyName
TestType
FolderPath
TestProgram
Remark
CreateTime
And this is what i have done
SELECT * FROM Program AS D
JOIN Family AS Q ON D.FamilyName = Q.FamilyName
JOIN Process AS V ON Q.TestQuant = V.PackageNo
JOIN Line AS R ON R.LineName = V.Line
WHERE V.Line = 'LINE1'
WHAT I HAVE CHANGE
SELECT DISTINCT D.FamilyName, D.TestType, D.FolderPath, D.TestProgram, D.Remark,
D.CreateTime
FROM Program D
INNER JOIN Family Q ON D.FamilyName = Q.FamilyName
INNER JOIN Process V ON Q.TestQuant = V.PackageNo
INNER JOIN Line R ON R.LineName = V.Line
WHERE V.Line = 'LINE1'
If you need ONLY the data from Program table, try this:
SELECT D.FamilyName, D.TestType, D.FolderPath, D.TestProgram, D.Remark, D.CreateTime
FROM Program D
JOIN Family Q ON D.FamilyName = Q.FamilyName
JOIN Process V ON Q.TestQuant = V.PackageNo
JOIN Line R ON R.LineName = V.Line
WHERE V.Line = 'LINE1'
It sounds like you may need a left or right outer join. Here is an example question that has some very good explanations of JOINs in the answers, the venn diagrams really helped me understand:
SQL JOIN and different types of JOINs
An example of how you might construct a join (taken from Techonthenet)
SELECT columns
FROM table1
RIGHT [OUTER] JOIN table2
ON table1.column = table2.column;
Hope this helps, SQL JOIN can be a bit tricky to understand.
Im having some problem with my SQL code. My assignment is to present some information about teachers(Lärare.personnummer) who don't have teach the course "Java2"(Kurstilfälle.kurs). The code is right but my problem is that there is one teacher who don't have teach any course(kurs). So the information about her is not in the result. I want to get this last persons information in my result.
My code--> http://imgur.com/QT3u4TL
Database--> https://ilearn2.dsv.su.se/mod/resource/view.php?id=21941
SELECT DISTINCT Person.personnummer, Person.namn, tjänsterum, telefon
FROM Kurstillfälle,
Person,
Lärare
WHERE Person.personnummer = Lärare.personnummer
AND Kurstillfälle.lärare = Person.personnummer
AND Lärare.personnummer NOT IN (SELECT Kurstillfälle.lärare
FROM Kurstillfälle WHERE kurs = 'Java2')
Maybe someone can help me with this. Thanks.
With new style JOIN, return a teacher who NOT EXISTS as teacher for Java2:
SELECT p.personnummer, p.namn, tjänsterum, telefon
FROM Person p
INNER JOIN Lärare l ON p.personnummer = l.personnummer
WHERE NOT EXISTS (SELECT 1 FROM Kurstillfälle
WHERE kurs = 'Java2'
AND lärare = p.personnummer)
Edit: I don't know Access syntax, but try INNER JOIN instead of just JOIN!
Using Joins this should get what you want
SELECT DISTINCT p.personnummer, p.namn, tjänsterum, telefon
FROM Kurstillfälle k
INNER JOIN Person p ON k.larare = p.personnummer
INNER JOIN Lärare l ON p.personnummer = l.personnummer
WHERE k.kurs !='Java2'
I am querying two tables and joining them together on people's names. I am trying to produce all employees who have not filled out a form within the past month. The problem I am encountering is I am receiving an overlap of names when people list their short name (Joe rather than Joseph, or Mike rather than Michael). How can I still produce the list of people without overlap, even when they use their short names?
This is the query I have as of now:
SELECT DISTINCT ge.employeeNo,
(ge.firstName + ' ' + ge.lastName) AS empName,
ge.email
FROM dbo.hist_Employees ge
INNER JOIN dbo.ctrl_Sites cs ON ge.locationID = cs.ID
WHERE (ge.firstName + ' ' + ge.lastName) NOT IN
(SELECT sc.recordedBy
FROM GRSTOPS.dbo.hist_StopCard sc
INNER JOIN dbo.ctrl_Area a ON sc.area = a.ID
INNER JOIN dbo.ctrl_Site s ON a.site = s.ID
WHERE sc.recorded BETWEEN '10/01/2013' AND '10/30/2013'
AND s.code = 'gre')
AND cs.Abbreviation = 'gre'
AND ge.employmentStatus = 1
AND ge.primaryDept <> 3
It would be better not to join on peoples names as they are not unique.
You should join using a primary key like ID/employeeNo etc.
I am trying to take a person and display their current insurance along with their former insurance. I guess one could say that I'm trying to flaten my view of customers or people. I'm running into an issue where I'm getting multiple records back due to multiple records existing within my left join subqueries. I had hoped I could solve this by adding "TOP 1" to the subquery, but that actually returns nothing...
Any ideas?
SELECT
p.person_id AS 'MIRID'
, p.firstname AS 'FIRST'
, p.lastname AS 'LAST'
, pg.name AS 'GROUP'
, e.name AS 'AOR'
, p.leaddate AS 'CONTACT DATE'
, [dbo].[GetPICampaignDisp](p.person_id, '2009') AS 'PI - 2009'
, [dbo].[GetPICampaignDisp](p.person_id, '2008') AS 'PI - 2008'
, [dbo].[GetPICampaignDisp](p.person_id, '2007') AS 'PI - 2007'
, a_disp.name AS 'CURR DISP'
, a_ins.name AS 'CURR INS'
, a_prodtype.name AS 'CURR INS TYPE'
, a_t.date AS 'CURR INS APP DATE'
, a_t.effdate AS 'CURR INS EFF DATE'
, b_disp.name AS 'PREV DISP'
, b_ins.name AS 'PREV INS'
, b_prodtype.name AS 'PREV INS TYPE'
, b_t.date AS 'PREV INS APP DATE'
, b_t.effdate AS 'PREV INS EFF DATE'
, b_t.termdate AS 'PREV INS TERM DATE'
FROM
[person] p
LEFT OUTER JOIN
[employee] e
ON
e.employee_id = p.agentofrecord_id
INNER JOIN
[dbo].[person_physician] pp
ON
p.person_id = pp.person_id
INNER JOIN
[dbo].[physician] ph
ON
ph.physician_id = pp.physician_id
INNER JOIN
[dbo].[clinic] c
ON
c.clinic_id = ph.clinic_id
INNER JOIN
[dbo].[d_Physgroup] pg
ON
pg.d_physgroup_id = c.physgroup_id
LEFT OUTER JOIN
(
SELECT
tr1.*
FROM
[transaction] tr1
LEFT OUTER JOIN
[d_vendor] ins1
ON
ins1.d_vendor_id = tr1.d_vendor_id
LEFT OUTER JOIN
[d_product_type] prodtype1
ON
prodtype1.d_product_type_id = tr1.d_product_type_id
LEFT OUTER JOIN
[d_commission_type] ctype1
ON
ctype1.d_commission_type_id = tr1.d_commission_type_id
WHERE
prodtype1.name <> 'Medicare Part D'
AND tr1.termdate IS NULL
) AS a_t
ON
a_t.person_id = p.person_id
LEFT OUTER JOIN
[d_vendor] a_ins
ON
a_ins.d_vendor_id = a_t.d_vendor_id
LEFT OUTER JOIN
[d_product_type] a_prodtype
ON
a_prodtype.d_product_type_id = a_t.d_product_type_id
LEFT OUTER JOIN
[d_commission_type] a_ctype
ON
a_ctype.d_commission_type_id = a_t.d_commission_type_id
LEFT OUTER JOIN
[d_disposition] a_disp
ON
a_disp.d_disposition_id = a_t.d_disposition_id
LEFT OUTER JOIN
(
SELECT
tr2.*
FROM
[transaction] tr2
LEFT OUTER JOIN
[d_vendor] ins2
ON
ins2.d_vendor_id = tr2.d_vendor_id
LEFT OUTER JOIN
[d_product_type] prodtype2
ON
prodtype2.d_product_type_id = tr2.d_product_type_id
LEFT OUTER JOIN
[d_commission_type] ctype2
ON
ctype2.d_commission_type_id = tr2.d_commission_type_id
WHERE
prodtype2.name <> 'Medicare Part D'
AND tr2.termdate IS NOT NULL
) AS b_t
ON
b_t.person_id = p.person_id
LEFT OUTER JOIN
[d_vendor] b_ins
ON
b_ins.d_vendor_id = b_t.d_vendor_id
LEFT OUTER JOIN
[d_product_type] b_prodtype
ON
b_prodtype.d_product_type_id = b_t.d_product_type_id
LEFT OUTER JOIN
[d_commission_type] b_ctype
ON
b_ctype.d_commission_type_id = b_t.d_commission_type_id
LEFT OUTER JOIN
[d_disposition] b_disp
ON
b_disp.d_disposition_id = b_t.d_disposition_id
WHERE
pg.d_physgroup_id = #PhysGroupID
In Sql server 2005 you can use OUTER APPLY
SELECT p.person_id, s.e.employee_id
FROM person p
OUTER APPLY (SELECT TOP 1 *
FROM Employee
WHERE /*JOINCONDITION*/
ORDER BY /*Something*/ DESC) s
http://technet.microsoft.com/en-us/library/ms175156.aspx
The pattern I normally use for this is:
SELECT whatever
FROM person
LEFT JOIN subtable AS s1
ON s1.personid = person.personid
...
WHERE NOT EXISTS
( SELECT 1 FROM subtable
WHERE personid = person.personid
AND orderbydate > s1.orderbydate
)
Which avoids the TOP 1 clause and maybe makes it a little clearer.
BTW, I like the way you've put this query together in general, except I'd leave out the brackets, assuming you have rationally named tables and columns; and you might even gain some performance (but at least elegance) by listing columns for tr1 and tr2, rather than "tr1.*" and "tr2.*".
Thanks for all of the feedback and ideas...
In the simplest of terms, I have a person table that stores contact information like name, email, etc. I have another table that stores transactions. Each transaction is really an insurance policy that would contain information on the provider, product type, product name, etc.
I want to avoid giving the user duplicate person records since this causes them to look for the duplicates prior to running mail merges, etc. I'm getting duplicates when there is more than 1 transaction that has not been terminated, and when there is more than 1 transaction that has been terminated.
Someone else suggested that I consider a cursor to grab my distinct contact records and then perform the sub selects to get the current and previous insurance information. I don't know if I want to head down that path though.
It's difficult to understand your question so first I'll throw this out there: does changing your SELECT to SELECT DISTINCT do what you want?
Otherwise, let me get this straight, you're trying to get your customers' current insurance and previous insurance, but they may actually have many insurances before that, recorded in the [transactions] table? I looked at your SQL for quite a few minutes but can't figure out what it all means, so could you please reduce it down to only the parts that are necessary? Then I'll think about it some more. It sounds to me like you need a GROUP BY somehow, but I can't work it out exactly yet.
Couldn't take the time to dig through all your SQL (what a beast!), here's an idea that might make things easier to handle:
select
p.person_id, p.name <and other person columns>,
(select <current policy columns>
from pol <and other tables for policy>
where pol.<columns for join> = p.person_id
and <restrictions for current policy>),
(select <previous policy columns>
from pol <and other tables for policy>
where pol.<columns for join> = p.person_id
and <restrictions for previouspolicy>),
<other columns>
from person p <and "directly related" tables>
This makes the statement easier to read by separating the different parts into their own subselects, and it also makes it easier to add a "Top 1" in without affecting the rest of the statement. Hope that helps.