Having trouble creating join looking for specific data - sql

I am using Oracle SQL (TeraTerm),
and
I am trying to join specific information from two tables CONSULTANT, and PROJECT_CONSULTANT, and I need to retrieve only the employees who worked over 40 hours. Here are the tables
Project Consultant
PROJECT_ID CONSULTANT_ID NUMBER_HOURS
--------------- --------------- ------------
94738949 49620928 6
45699847 34879223 57
45699847 95928792 44
45699847 04875034 59
19870398 49620928 32
30495394 95928792 57
30495394 07811473 50
62388923 07811473 82
and Consultant
CONSULTA NAME ZIP START_DT
-------- -------------------------------- ----- ---------
CON_TITLE
-------------------------
49620928 Tom Jones 39875 01-SEP-98
Junior Consultant
04875034 Jack Johnson 29087 05-OCT-93
Manager
34879223 Lanny Harris 03944 30-APR-04
Principal
CONSULTA NAME ZIP START_DT
-------- -------------------------------- ----- ---------
CON_TITLE
-------------------------
95928792 Michael Johnson 02953 22-JUN-02
Senior Manager
07811473 Wendy Adams 29087 05-JUL-05
Senior Consultant
The code I came up with is
select Consultant_ID, Name, Zip, and Number_Hours
from Consultant
Inner Join project_consultant
ON Consultant.Consultant_ID=project_consultant.Consultant_ID
WHERE project_consultant.number_Hours>40;
I am getting an error
ERROR at line 1:
ORA-00936: missing expression
I just wanna know how to write the join statement correctly any help would be awesome, because I am having trouble knowing how to fix this join statement

You don't use and in the select clause:
select c.Consultant_ID, c.Name, c.Zip, pc.Number_Hours
from Consultant c Inner Join
project_consultant pc
on c.Consultant_ID = pc.Consultant_ID
where pc.number_Hours > 40;
You also need a table alias in the select clause to be clear what table Consultant_Id refers to.
EDIT:
You might actually want to sum the hours for employees. If so, you need an aggregation:
select c.Consultant_ID, c.Name, c.Zip, sum(pc.Number_Hours)
from Consultant c Inner Join
project_consultant pc
on c.Consultant_ID = pc.Consultant_ID
group by c.Consultant_ID, c.Name, c.Zip
having sum(pc.number_Hours) > 40;

You can't use and in Select Clause
Try this
SELECT C.Consultant_ID, C.Name, C.ip, PC.Number_Hours
FROM Consultant C
INNER Join project_consultant PC
ON C.Consultant_ID=PC.Consultant_ID
WHERE PC.number_Hours > 40;

select c.Consultant_ID, c.Name, c.Zip, p.Number_Hours
from Consultant c
Inner Join project_consultant p
ON c.Consultant_ID=p.Consultant_ID
WHERE p.number_Hours>40;

Related

How to use all records from another table as counting columns?

I have 4 tables:
location:
location_id name
------------------------
1 France
device:
device_id location_id model_id
-------------------------------------
1 1 1
2 1 2
3 1 3
model:
model_id family_id name
-------------------------------------
1 1 C-max
2 1 S-max
3 2 Vectra
and family:
family_id name
---------------------
1 Ford
2 Opel
I need to build a complicated SQL query now. As the result, I would like to receive this:
location_id name Ford Opel
------------------------------------------
1 France 2 1
Is it possible to do it in SQL at all? I see there there problems:
About using other table records as columns in the query
About nested tables
About counting the elements (count function?)
Any comments/reference materials will be for me helpful. I do not await the final code.
In SQL queries the columns are fix. You get more or less rows depending on data, not columns. But that doesn't matter, because SQL is about to get data not to display it. The latter is a task for the GUI layer.
So get the desired data, which is the number of models per location and family mainly.
select l.location_id, l.name as location_name, f.name as family_name, count(*) as models
from location l
join device d on d.location_id = l.location_id
join model m on m.model_id = d.model_id
join family f on f.family_id = m.family_id
group by l.location_id, l.name, f.name
order by l.location_id, l.name, f.name;
This is all you need from the database. How to show the data is a task for your programm, a Delphi app in your case. So use Delphi to read the data with above query and fill your grid in a simple loop.
Thank you all for your helpful tips.
I solved my problem using the static method and the code published by #Matt. Because somebody else may looking for the solution, I paste here my working query for PostgreSQL:
SELECT DISTINCT t.location_id, t.name, SUM(t.ford) AS ford, SUM(t.opel) as opel
FROM(
SELECT l.location_id, l.name,
(SELECT COUNT(m.family_id) WHERE m.family_id = '1') AS ford,
(SELECT COUNT(m.family_id) WHERE m.family_id = '2') AS opel
FROM location l
INNER JOIN device d ON l.location_id = d.location_id
INNER JOIN model m ON d.model_id = m.model_id
INNER JOIN family f ON m.family_id = f.family_id
GROUP BY l.location_id, l.name, m.family_id
) t
GROUP BY t.location_id;

Usage of joins: getting the oppsite result

I am working with oracle and below I have a basic sql query where I select the schools that have a team using a join. However I am struggling how can I select the opposite(schools that don’t have a team) using a join as well. I tried using the words outter, inner, left and right but to no avail I get the results that I desired. How can I list the schools that don’t have a team?
Query:
SELECT DISTINCT a.school_name, a.school_id, b.school_id FROM School a RIGHT OUTER JOIN Team b ON a.school_id = b.school_id;
Results:
SCHOOL_NAME SCHOOL_ID SCHOOL_ID
------------------------- ---------- ----------
Panthers University 92022 92022
Blue Rays Middle School 22149 22149
Tables:
schools
SCHOOL_ID SCHOOL_NAME SCHOOL_TYPE
---------- ----------------------------- ------------
92022 Panthers University University
22149 Blue Rays Middle School Middle SchooL
21719 Bull Dogs High School High SchooL
42736 Saint Lucia Grade School Middle SchooL
school_teams
TEAM_ID SPORT_ID SCHOOL_ID TEAM_NAME
---------- ---------- ---------- ----------
1 1 92022 Panthers
2 1 22149 Blue Rays
Use Not exists to do this.
SELECT a.school_name, a.school_id
FROM School a
where not exists (select 1 from Team b where a.school_id = b.school_id)
All those joins (inner, outer, left, right) select only rows that match. You are looking for rows that DON'T match, so they won't suit you.
Try this:
SELECT DISTINCT school_id, school_name FROM school
WHERE school_id not in
(SELECT school_id FROM school_teams)
try:
SELECT DISTINCT a.school_name, a.school_id, b.school_id FROM School a LEFT OUTER JOIN Team b ON a.school_id = b.school_id;
Write this query to generate the required result set. Use Left Join.
SELECT Table1.School_Name, Table1.School_Id FROM Table1 LEFT JOIN Table2 ON Table1.School_Id = Table2.School_Id where Table1.School_Id NOT IN (Select DISTINCT Table2.School_Id From Table2);

SQL query get course number for certain student grades

I'm working through some problems and I can't seem to get the expected results for this one. The question is below with what is in my code right now and also the expected results. If anyone help that would be great. I'm just trying to get a understanding on this and can't seem to get my head around what exactly this is asking as you can see my code I have now isn't close to what the expected result is as of right now. Also I added the schema this will show whats in what table if needed for your guys help.
Question:
List the course number of courses wherein students have received grades for every one of the possible defined grade types. Order by course number.
My code so far:
SELECT g.Student_id, g.Grade_type_code
FROM Grade g LEFT OUTER JOIN Section s
ON g.Section_id = s.Section_id
GROUP BY g.Student_id, g.Grade_type_code
ORDER BY g.Student_id;
Any help would be great, also here is the Schema.
DBMS: I'm using Oracle SQL Developer
Here is the Expected Result
COURSE_NO
----------
20
25
100
120
122
125
130
135
Note: The Chapter for this problem is based off using
LEFT OUTER JOIN
My Current results
STUDENT_ID GRADE_TYPE_CODE
---------- ---------------
102 FI
102 HM
102 MT
102 PA
102 QZ
103 FI
103 HM
103 MT
103 PA
103 QZ
104 FI
104 HM
Based on your ER diagram I believe this query should return a list of courses whose enrolled students have collectively received all of the grade types listed in the GRADE_TYPE table.
select s.course_no,
c.descr,
count(distinct g.grade_type_code) as num_grade_types
from grade g
join enrollment e
on g.student_id = e.student_id
and g.section_id = e.section_id
join section s
on e.section_id = s.section_id
join course c
on s.course_no = c.course_no
group by s.course_no, c.descr
having count(distinct g.grade_type_code) = (select count(grade_type_code)
from grade_type)
I didn't notice your expected result was only the course # (you can just get rid of the columns you don't want from the select list). Also the join to the COURSE table is only there to get the course description, so if you don't want the course description selected, you do not need that join.
You need to select COURSE_NO instead. And also use JOIN and not LEFT JOUTER JOIN.
Something like this:
select COURSE_NO from
(
SELECT distinct (s.COURSE_NO)
FROM Grade g JOIN Section s
ON g.Section_id = s.Section_id
)
ORDER BY s.COURSE_NO;

SQL Query involving joins

For an SQL assessment I have to carry out a query where I need to list the Car Sales in the past month ordered by Salesman Code.
I have created an SQL statement. However, when I run it, it lists nothing at all except the column names that I have included within the query. The SQL code I have used is below:
SELECT CarForSale.SalesmanCode,
Salesman.SalesmanName,
Customer.CustomerCode,
Customer.CustomerName,
Customer.CustomerAddress
FROM
(
Centre
INNER JOIN Customer
ON Centre.CentreCode = Customer.CentreCode
)
INNER JOIN CarForSale
ON (Customer.CustomerCode = CarForSale.CustomerCode)
AND (Centre.CentreCode = CarForSale.CentreCode), Salesman
WHERE CarForSale.CFSSoldDate BETWEEN CVDATE('01/02/2013') AND CVDATE('01/03/2013')
ORDER BY Salesman.SalesmanCode;
If anyone has any feedback or knows where I am going wrong I would much appreciate some assistance with this problem.
Here is some sample data as requested:
CFS Table
CFSCode CFSMake CFSModel CFSSellingPrice
000001 Mercedes W168 45000
CFSSoldDate CentreCode SalesmanCode CustomerCode
01/03/2013 00000001 0000000001 00000001
Salesman Table
SalesmanCode SalesmanName SalemanCommThisYear SalesmanStatus CentreCode
0000000001 Liam Jones 2250 senior 00000001
customer table
CustomerCode CustomerName CustomerAddress CentreCode CustomerStatus
00000001 Gina Smith 1, The Lake, 00000002 good
Merthyr Tydfil
In your current query, you have some unusual syntax:
AND (Centre.CentreCode = CarForSale.CentreCode), Salesman -- what's this
I am not sure what the , Salesman is supposed to be doing. But if you are trying to JOIN on the Salesman table, then your query will be:
SELECT CarForSale.SalesmanCode,
Salesman.SalesmanName,
Customer.CustomerCode,
Customer.CustomerName,
Customer.CustomerAddress
FROM ((Centre
INNER JOIN Customer
ON Centre.CentreCode = Customer.CentreCode)
INNER JOIN CarForSale
ON (Customer.CustomerCode = CarForSale.CustomerCode)
AND (Centre.CentreCode = CarForSale.CentreCode)))
INNER JOIN Salesman
ON CarForSale.SalesmanCode = Salesman.SalesmanCode
WHERE CarForSale.CFSSoldDate BETWEEN #01/02/2013# AND #01/03/2013#
ORDER BY Salesman.SalesmanCode;
Also in MS Access, when using dates, they should be surrounded by pound sigs #. Your query should be:
SELECT CarForSale.SalesmanCode,
Salesman.SalesmanName,
Customer.CustomerCode,
Customer.CustomerName,
Customer.CustomerAddress
FROM ((Centre
INNER JOIN Customer
ON Centre.CentreCode = Customer.CentreCode)
INNER JOIN CarForSale
ON (Customer.CustomerCode = CarForSale.CustomerCode)
AND (Centre.CentreCode = CarForSale.CentreCode)))
INNER JOIN Salesman
ON CarForSale.SalesmanCode = Salesman.SalesmanCode
WHERE CarForSale.CFSSoldDate BETWEEN #01/02/2013# AND #01/03/2013#
ORDER BY Salesman.SalesmanCode;
Edit #1, I am not sure why you are joining on the Centre table since you are not using it for anything. I just ran the following query in MS Access using your sample data and got results:
SELECT CarForSale.SalesmanCode,
Salesman.SalesmanName,
Customer.CustomerCode,
Customer.CustomerName,
Customer.CustomerAddress
FROM (Customer
INNER JOIN CarForSale
ON Customer.CustomerCode = CarForSale.CustomerCode)
INNER JOIN Salesman
ON CarForSale.SalesmanCode = Salesman.SalesmanCode
WHERE CarForSale.CFSSoldDate BETWEEN #01/02/2013# AND #01/03/2013#
ORDER BY Salesman.SalesmanCode;

Oracle SQL Syntax: Inner Join

I don't have access to an Oracle Database right now, so I'm posting my question here:
Is the following statement valid Oracle SQL Syntax?
SELECT a1
FROM t1 INNER JOIN t2
I'm particularly wondering whether we need to specify a join attribute for the inner join.
Best,
Will
You're missing ON
Like
SELECT a1
FROM t1 INNER JOIN t2
ON t1.SomeID = t2.SomeID
So, this is the query you're thinking of....
SQL> select e.ename
2 , d.dname
3 from emp e inner join dept d
4 /
from emp e inner join dept d
*
ERROR at line 3:
ORA-00905: missing keyword
SQL>
As we can see, it fails. The INNER JOIN syntax demands that we provide columns to join on ...
SQL> select e.ename
2 , d.dname
3 from emp e inner join dept d
4 on ( d.deptno = e.deptno )
5 /
ENAME DNAME
---------- --------------
SCHNEIDER ACCOUNTING
BOEHMER ACCOUNTING
KISHORE ACCOUNTING
ROBERTSON RESEARCH
...
FEUERSTEIN HOUSEKEEPING
PODER HOUSEKEEPING
TRICHLER HOUSEKEEPING
21 rows selected.
SQL>
There is an alternative syntax, the NATURAL JOIN. This syntax will automatically join the two tables on the basis of all columns which share the same name.
SQL> select e.ename
2 , d.dname
3 from emp e natural join dept d
4 /
ENAME DNAME
---------- --------------
SCHNEIDER ACCOUNTING
BOEHMER ACCOUNTING
KISHORE ACCOUNTING
ROBERTSON RESEARCH
...
FEUERSTEIN HOUSEKEEPING
PODER HOUSEKEEPING
TRICHLER HOUSEKEEPING
21 rows selected.
SQL>
This is a neat trick but really shouldn't be relied upon in production code; it is a bug waiting to happen.
You will need to add an ON clause
SELECT a1
FROM t1 INNER JOIN t2 on t1.a1=t2.a1
Yes, you have to specify join condition:
FROM t1 INNER JOIN t2 on t1.f = t2.f