not displaying 'none' instead of a 0 - sql

Right now my query is giving me a 0 when I count the enrolled date. How could I have a row show me 'none' result instead of a 0.
what I am missing here ?
COALESCE(TO_CHAR(SUM(ENROLLMENTS)),'none') ENROLLMENTS
this is what I have
SELECT lt.STUDENT_ID,lt.FIRST_NAME, lt.LAST_NAME,COALESCE(TO_CHAR(SUM(ENROLLMENTS)),'none') ENROLLMENTS
FROM STUDENT lt
LEFT OUTER JOIN
(SELECT s.STUDENT_ID, z.COURSE_NO,COUNT(e.ENROLL_DATE) AS ENROLLMENTS
FROM STUDENT s
LEFT JOIN ENROLLMENT e ON s.STUDENT_ID = e.STUDENT_ID
LEFT JOIN SECTION z ON e.SECTION_ID = z.SECTION_ID
WHERE s.PHONE LIKE '702%'
GROUP BY s.STUDENT_ID, z.COURSE_NO) rt
ON lt.STUDENT_ID = rt.STUDENT_ID
WHERE lt.PHONE LIKE '702%'
GROUP BY lt.STUDENT_ID,lt.FIRST_NAME, lt.LAST_NAME,ENROLLMENTS
ORDER BY lt.LAST_NAME,lt.FIRST_NAME;
instead of having results
STUDENT_ID FIRST_NAME LAST_NAME ENROLLED
---------- ------------------------- ------------------------- -----------
253 Walter Boremmann 1
396 James E. Norman 0
etc
I'd like to have it like this
STUDENT_ID FIRST_NAME LAST_NAME ENROLLED
---------- ------------------------- ------------------------- -----------
253 Walter Boremmann 1
396 James E. Norman none
etc

I think you need a CASE statement because TO_CHAR is returning "0":
(CASE WHEN SUM(ENROLLMENTS)=0 THEN 'none' ELSE SUM(ENROLLMENTS) END) ENROLLMENTS

Related

Retrieving dissimilar data using WHERE NOT in the joins?

I need to retrieve the name of those departments in which no students are enrolled.
Table: department
dept_id dept_name
1 IT
2 Electrical
3 Civil
4 Mechanical
5 Chemical
Table: stud_member
f_name dept_id age
AB 2 19
Rose 3 22
May 1 20
Noor 1 21
Haya 1 19
April 3 23
Sakina 2 20
For example the names of mechanical and chemical. I have written this query for it using outer join (explicitly maybe?) But is shows an error.
please tell me that why i cannot write:
SELECT dept_id, dept_name
FROM department
LEFT JOIN stud_member ON (WHERE NOT department.dept_id = stud_member.dept_id);
I will be grateful if anyone will tell me the correct answer!
Assuming dept_id in stud_member can not be NULL which is true when dept_id is a FOREIGN KEY
SELECT dept_id, dept_name
FROM department
WHERE dept_id NOT IN (SELECT dept_id FROM stud_member);
as suggested using NOT EXISTS does not have this problem
SELECT d.dept_id, d.dept_name
FROM department d
WHERE NOT EXISTS (SELECT * FROM stud_member s WHERE d.dept_id = s.dept_id);
You can select all departments where Right part of Left JOIN is NULL
SELECT d.dept_id, d.dept_name
FROM department d
LEFT JOIN stud_member sm ON d.dept_id = sm.dept_id
WHERE sm.dept_id IS NULL

Case Statement With Multiple Joins

I have two tables, emp and location. I need to fetch the records for all the matching eid s' of emp table based on location type.
If the location type=2 then we need to fetch the city associated with it.
If we don't have type=2 record we need to fetch type=1 associated city for the matching eid.
My case statement works fine until there are two records for the eid of both type 1 and type 2. But I need to fetch only type 2 in this case
select case when a.type=2 then a.city
When a.type=1 then a.city
Else '0' End As City
From location a
Join emp r
On a.eid=r.eid
emp table
eid ename
1 james
2 mark
3 kristie
4 john
5 allen
location table
city eid type
athens 1 2
melbourne 2 1
london 2 2
newyork 3 1
output:
eid ename city type
1 james athens 2
2 mark london 2
3 kristie newyork 1
I think the most direct way to represent what you're asking for is:
select coalesce(l2.city, l1.city, '0') as city
From emp r
left join location l1
on l1.eid = r.eid
and l1.type=1
left join location l2
on l2.eid = r.eid
and l2.type=2
The subquery-based solution proposed by Jeremy Real may also work, but it assumes that 1 and 2 are they only values in the table for location.type (and I just don't find it to be as intuitive).
Try this:
select a.eid
,r.ename
,case when a.type=2 then b.city
when a.type=1 then b.city
else '0' End As City
from (
select a.eid, max(a.type) as type
From location a
group by a.eid
) a
right outer join location b
on a.eid = b.eid and a.type=b.type
inner join emp r
on b.eid=r.eid
You want to rank your cities. Use ROW_NUMBER to do that:
select e.eid, e.name, l.city, l.type
from emp e
join
(
select
city, eid, type,
row_number() over (partition by eid order by type desc) as rn
from location
) l on l.eid = e.eid and l.rn = 1;
rn is 1 for the better city per eid (where "better" is the one with the higher type).

SQL: Names of courses that Mike can take next semester

Mike can take a CS course X only if he has not successfully finished X, or he has successfully finished all the courses on which course X is built. For example, Mike cannot take IE2900, because he has not successfully finished IE2700.
(In the query, only the courses on which a course is directly built should be considered. For example, IE3200 is only directly built on IE2201, not on IE1100).
In short, find a query for codes of CS courses that Mike can take next semester.
The result should be like the following:
Code
----
IE2700
IE3200
Below are the database tables with example data:
Students
Sid Name
---------- ----------
2 Kathlyn
6 Mike
7 Nick
9 Anny
Courses
Code Title Dept Credits
---------- ----------- ---------- ----------
IE1100 programming CS 10
IE2201 operating s CS 20
IE2700 database CS 10
IE2900 software en CS 10
IE3200 distributed CS 10
MAT1001 calculus Math 30
DOK1012 database Hum 10
CoursesBuiltOn
Code BuiltOn
---------- ----------
IE2201 IE1100
IE2700 IE1100
IE2900 IE2201
IE2900 IE2700
IE3200 IE2201
Grades
Sid Code Year Grade
---------- ---------- ---------- ----------
2 MAT1001 2010 A
2 IE1100 2011 A
2 IE2201 2012 A
2 IE2700 2013 A
2 IE2900 2014 B
2 IE3200 2014 B
6 MAT1001 2011 D
6 IE1100 2012 C
6 IE2201 2013 B
6 IE2700 2013 F
7 MAT1001 2013 B
7 DOK1012 2013 A
9 MAT1001 2013 F
The database structure:
CREATE TABLE Students (
Sid TEXT PRIMARY KEY,
Name TEXT
);
CREATE TABLE Courses (
Code TEXT PRIMARY KEY,
Title TEXT,
Dept TEXT,
Credits INT
);
CREATE TABLE Grades (
Sid INT,
Code TEXT,
Year INT,
Grade TEXT,
PRIMARY KEY (Sid, Code),
FOREIGN KEY (Sid) REFERENCES Students (Sid),
FOREIGN KEY (Code) REFERENCES Courses (Code)
);
CREATE TABLE CoursesBuiltOn (
Code TEXT,
BuiltOn TEXT,
PRIMARY KEY (Code, BuiltOn),
FOREIGN KEY (Code) REFERENCES Courses (Code),
FOREIGN KEY (Code) REFERENCES Courses (BuiltOn)
);
I tried to join all the tables together on their foreign keys and get out information, but I could not find any way to get the right answer.
EDIT:
This is what I got so far:
with NotAvailable as (select COB.Code
from Courses C
left join CoursesBuiltOn COB on COB.BuiltOn = C.Code
left join Grades Gr on Gr.Code = C.Code
inner join Students S on S.Sid = Gr.Sid
where Gr.Sid = S.Sid and Gr.Grade = 'F'
), AlreadyTakenAndPassed as (select Gr.Code
from Grades Gr where Gr.Sid = S.Sid and Gr.Grade <> 'F'
), TakenButNotYetPassed as (select Gr.Code
from Grades Gr where Gr.Sid = S.Sid and Gr.Grade = 'F'
)
select COB.Code
from Courses C
left join CoursesBuiltOn COB on COB.BuiltOn = C.Code
left join Grades G on G.Code = C.Code
inner join Students S on G.Sid = S.Sid
where C.Dept = 'CS' and S.Name = 'Mike'
and (COB.Code in TakenButNotYetPassed or COB.Code not in NotAvailable or COB.Code not in AlreadyTakenAndPassed)
;
Code
----------
IE2700
IE2900
IE3200
IE2900
select COB.Code
from Courses C
left join CoursesBuiltOn COB on COB.BuiltOn = C.Code
left join Grades G on G.Code = C.Code
inner join Students S on S.Sid = G.Sid
where S.Name = 'Mike' and G.Grade = 'F';
Code
----------
IE2900
As you can see in the query above, I wanted to make subqueries that will exclude courses from the whole set of the courses. However, the NotAvailable subquery will not exclude IE2900. Why is that? I thought I was on the right way... this might not be the most efficient approach touch...
I did it myself, by cutting the total query into cases:
with
TakenButNotYetPassed as (select Gr.Code
from Grades Gr
inner join Students St on St.Sid = Gr.Sid
where St.Name = 'Mike' and Gr.Grade = 'F'
),
NotAvailable as (select Code
from CoursesBuiltOn
where BuiltOn in TakenButNotYetPassed
),
Passed as (select Gr.Code
from Grades Gr
inner join Students St on St.Sid = Gr.Sid
where St.Name = 'Mike' and Gr.Grade <> 'F'
)
select *
from Courses C
where C.Dept = 'CS'
and C.Code not in Passed
and C.Code not in NotAvailable
;

Create view by joining three tables in SQL

I have three tables STUDENTS, SUBJECTS, RANK ,with data as -
1) STUDENTS [NAME(Primary)]
NAME
--------
Alex
Greg
2) SUBJECTS [ID(Primary)]:
ID
--------
100
101
102
3) RANK [SEQ(Primary), NAME, ID, RANK]
SEQ NAME ID RANK
------ ------- ------ ------
1 Alex 100 A
2 Greg 100 A
3 Greg 101 B
I want to create a view that should display data as
NAME ID RANK
------- ------ ------
Alex 100 A
Alex 101 Z
Alex 102 Z
Greg 100 A
Greg 101 B
Greg 102 Z
So, for every student and for every subject, the View should display the RANK if present in RANK table, else replace the NULL with 'Z'.
I'm a newbie to SQL. So any help in forming the query would be deeply appreciated!
cross join student and subject then left outer join the result with rank to get ranks for all (student, subject) combination. selecting column with NVL OR COALESCE will replace NULL with 'z'.
SELECT st.name,
su.id,
NVL(ra.rank,'Z') Rank, --COALESCE(ra.rank,'Z') Rank
FROM student st
CROSS JOIN subject su
LEFT OUTER JOIN rank ra
ON ra.name = st.name
AND ra.id = su.id
ORDER BY st.name,su.id
Note : ORDER BY can be removed from above query if you don't need.
fiddle
SELECT r.NAME, r.ID, NVL(r.RANK, 'Z')
FROM RANK r, studendts st, SUBJECTS su
WHERE st. NAME = r. NAME
AND su.ID = r.ID
ORDER BY 1,2,3

how to display a row that is null instead of 0

I am getting a correct result, but now instead of showing me result that is 0 I want them to show me null result . How could I get results null instead of 0 ?
SELECT w.FIRST_NAME,w.LAST_NAME,COUNT(s.SECTION_ID) AS COUNTED_SECTIONS
FROM INSTRUCTOR w LEFT OUTER JOIN SECTION s
ON w.INSTRUCTOR_ID = s.INSTRUCTOR_ID
GROUP BY w.FIRST_NAME,w.LAST_NAME
ORDER BY w.LAST_NAME;
currently showing
FIRST_NAME LAST_NAME COUNTED_SECTIONS
------------------------- ------------------------- ----------------
Rick Chow 0
Marilyn Frantzen 10
Fernand Hanks 9
Charles Lowry 0
etc
but I want
FIRST_NAME LAST_NAME COUNTED_SECTIONS
------------------------- ------------------------- ----------------
Rick Chow
Marilyn Frantzen 10
Fernand Hanks 9
Charles Lowry
etc
I've tried it with NVL and it doesn't work
NVL(COUNT(s.SECTION_ID),NULL) AS COUNTED_SECTIONS
I think NULLIF() is available in oracle:
SELECT w.FIRST_NAME,w.LAST_NAME,NULLIF(COUNT(s.SECTION_ID),0) AS COUNTED_SECTIONS
FROM INSTRUCTOR w LEFT OUTER JOIN SECTION s
ON w.INSTRUCTOR_ID = s.INSTRUCTOR_ID
GROUP BY w.FIRST_NAME,w.LAST_NAME
ORDER BY w.LAST_NAME;
Try nullif:
SELECT w.FIRST_NAME,w.LAST_NAME, NULLIF(COUNT(s.SECTION_ID), 0) AS COUNTED_SECTIONS
FROM INSTRUCTOR w LEFT OUTER JOIN SECTION s
ON w.INSTRUCTOR_ID = s.INSTRUCTOR_ID
GROUP BY w.FIRST_NAME,w.LAST_NAME
ORDER BY w.LAST_NAME;
You can use DECODE in order to decide what you want to display
DECODE(COUNT(s.SECTION_ID),0, NULL, COUNT(s.SECTION_ID)) AS COUNTED_SECTIONS