Selecting values from one column based on a different columns value - sql

Having trouble stating my problem succinctly here, so I'll just give an example.
Let's say I have a DB2 table about Students:
Name Class Grade
Billy J Econ A
Sarah S Maths B
Greg X Computes A-
Billy J Maths D
Greg X Maths C+
And I want to retrieve those students that are in both Econ and Maths, and display the information thusly:
Name Maths Grade Econ Grade
Billy J D A
How in the world can I accomplish this?

This solution will solve the problem for the two classes you named:
SELECT Name, Math.Grade AS MathsGrade, Econ.Grade AS EconGrade
FROM Students Math INNER JOIN Students Econ ON Math.Name = Econ.Name
WHERE Math.Class = 'Maths' AND Econ.Class = 'Econ'
The only thing that this solution doesn't do is include the spaces in your derived column names. You can do that by writing Maths Grade and Econ Grade in whatever characters DB2 uses for identifier quotes.
To be included students must have both a Maths and an Econ grade.

SELECT * from Students
where id in
(SELECT id from Students where Class = 'Econ')
AND id in
(SELECT id from Students where Class = 'Math');

Related

SQL selecting where A equals both B and C

name | course
Jay | LAWS0001
Mark | LAWS0002
Sam | LAWS0002
Alice | LAWS0001
Ryan | LAWS0001
Ryan | LAWS0002
Hey guys, I've got this database and I want to only select the names that take both 'LAWS0001' and 'LAWS0002'. So from this example, it should select 'Ryan' because he's the only person to take both courses.
I tried IN operator:
SELECT name
FROM student
WHERE course IN ('LAWS0001', 'LAWS0002')
but this takes everyone because everyone is taking either of the courses.
Is there an operator for my problem?
You can use your existing query, using a GROUP BY clause to COUNT the number of distinct courses each student is taking in the set ('LAWS0001', 'LAWS0002') and only selecting those students where the count is 2:
SELECT name
FROM student
WHERE course IN ('LAWS0001', 'LAWS0002')
GROUP BY name
HAVING COUNT(DISTINCT course) = 2
Demo on SQLFiddle

SQL Newbie Stuck on Manager Flag Field Logic

This is my first month of being a Data Analyst, and I can't seem to find an answer that is specific enough to my problem here to help. I am having trouble getting this manager flag field to work and I think I'm getting confused by the joins.
The goal is to match the EMPLIDs of JOB_VW A to see if they exist in the Supervisor_ID column of Supervisor_VW K. Supervisor_VW K has ALL employees in the company (including supervisors) in the K.EMPLID column. Someone can be in both the supervisor ID column and EMPL column at the same time, but in different rows. The SUP ID is the EMPL ID of someone in a manager position.
For example:
Supervisor_VW K
EMPL ID EMPL NAME SUP ID SUP NAME
1 Smith, John 2 William, Mark
5 Jarvis, John 2 William, Mark
2 William, Mark 4 Rover, Spot
The results I am getting are as such
QUERY RESULTS
EMPLID EMPL NAME MANAGER FLAG
2 William, Mark Y
2 William, Mark Y
4 Rover, Spot Y
1 Smith, John N
5 Jarvis, John N
My current code is as follows:
SELECT CASE WHEN K.Supervisor_Id IS NULL THEN
'N'
ELSE
'Y'
END AS "ManagerFlag".....
FROM (SELECT K.*
FROM SUPERVISOR_VW K, JOB_VW A
WHERE K.SUPERVISOR_ID (+) = A.EMPLID
AND EXISTS (SELECT K1.EMPLID, K1.SUPERVISOR_ID
FROM SUPERVISOR_VW K1
WHERE K1.EMPLID IN K1.Supervisor_Id)
) K
So it seems that I am getting duplicate supervisor rows for every single employee that they supervise. If they supervise only one person, I get a singular row. If they supervise 20, I get 20 duplicate rows of that supervisor. HOWEVER, their employee that they supervise shows up in the table without issue and is properly labeled as N, no duplicates.
If anyone could help, please do! I appreciate you reading through my work, let me know if more info is required.
The usual way to achieve the desired result is like this:
select emplid, emplname,
case when emplid in (select supid from supervisor_vw) then 'Y'
else 'N' end as managerflag
from supervisor_vw;

Selecting more after group-by while using join

At the moment I am busy with two tables, Students and Classes. These two both contain a column project_group, a way to categorize multiple students from one class into smaller groups.
In the Students table there is a column City that states in which town/city students live, from the rows that have been filled there are already several cities occurring multiple times. The code I used to check how many times a city is being showed is this:
SELECT City, count(*)
FROM Students
GROUP BY City
Now the next thing I want to do is show per class in which cities the students live and how many live there, so for example a result like:
A | - | 2
A | New York | 3
A | Los Angeles | 1
B | - | 1
B | Miami | 2
B | Seattle | 1
Students and Classes can join each other on the column project_group but what I'm mostly interested in his using both the GROUP BY mentioned earlier, using the JOIN and also showing the results per class.
Thanks in advance,
KRAD
I'm not sure what the column name is for A and B in your example. I'm assuming Classes.Class in the following:
SELECT
C.Class
, S.City
, COUNT(S.*) AS Count
FROM
Classes AS C INNER JOIN
Students AS S ON C.Project_Group = S.Project_Group
GROUP BY
C.Class
, S.City
I managed to get it working. While doing some tests to see which exact error message it was that I got, I used this and managed to get it working. I now get an overview per class that shows how many people live in which city. This is the code used.
SELECT class_id, city, count(*) AS amount
FROM students, classes
WHERE students.project_group = classes.project_group
GROUP BY class_id, city
ORDER BY class_id

SQL Count unique rows where a column contains two different values

I have taken a good look around and not been able to find any questions that match mine. Maybe I am not using the right language when searching or whatever, but here goes.
I have an SQL table called Classes that looks something like this
Student_Name | Class
--------------------
Edgar | Chemistry
Allan | Chemistry
Burt | Chemistry
Edgar | Math
Sue | Math
Hamilton | Math
Edgar | English
Sue | English
Edgar | German
Ben | German
I want to count how many students are taking both Math and German.
Assuming the following in this example:
- Student names are unique
- One student can have many classes
Logically I would use a select statement to get a result set of students who are taking Math. Then I would go through each Student_Name from the result set and check them against the table to see how many are taking German.
In this case I would expect a return of 1 as only Edgar is taking both Math and German.
Here are some of the queries I have tried so far to no avail :-(
This one was after doing some research on DISTINCT:
SELECT COUNT(DISTINCT Student_Name) FROM Classes WHERE Class = 'Math' AND Class = 'German';
And this one was after finding out more about GROUP BY:
SELECT COUNT(*) FROM (
SELECT DISTINCT Student_Name FROM Classes
WHERE Class IN ( 'Math', 'German' )
GROUP BY Student_Name
);
Neither of these came out quite right any help would be highly appreciated.
SELECT COUNT(*) totalStudent
FROM
(
SELECT student_name
FROM Classes
WHERE class IN ('Math','German')
GROUP BY student_name
HAVING COUNT(*) = 2
) subAlias
SQLFiddle Demo
OUTPUT
╔══════════════╗
║ TOTALSTUDENT ║
╠══════════════╣
║ 1 ║
╚══════════════╝
Could also do the following:
select count(distinct a.Student_name)
from Classes a inner join Classes b on
a.Class = 'German' and
b.Class = 'Math' and
a.Student_Name = b.Student_name;
This solves the problem where the table contains duplicate rows (as pointed out by a commenter to another answer)

SQL query help needed joining within a table

I have a table called babynames that looks abit like this:
firstname |sex |year |count
Bob |M| 2010| 150
Bob |M| 2009| 100
Bob |M| 2008| 122
Bob |F| 2007| 2
Bob |F| 2001| 1
What I want to do is get a list of all the baby names that are both female and male, so my query needs to pull all the firstname records that have at least two records in the table and are at least one M and one F.
It's getting late and my mind isn't working well tonight. Can anyone suggest a string that might help me achieve this task?
There are several ways to handle this. One would be to to use a COUNT(DISTINCT sex) = 2 in the HAVING clause. Be sure to GROUP BY firstname.
SELECT
firstname
FROM babynames
GROUP BY firstname
HAVING COUNT(DISTINCT sex) = 2
Here's a demo: http://sqlfiddle.com/#!2/5d221/1
Another would an INNER JOIN against 2 aliases of the same table, where one looks for M while the other looks for F. If a name isn't matched by both conditions, the join can't be made and it will get excluded from the output.
SELECT
DISTINCT
m.firstname
FROM
babynames f
INNER JOIN babynames m ON f.firstname = m.firstname
WHERE
f.sex = 'F'
AND m.sex = 'M'
http://sqlfiddle.com/#!2/5d221/3