Why does my view query split into two? - sql

I am trying to create a view that records the selected attributes for all Computer Science majors.
This is my query to create a view:
DROP VIEW CS_grade_report;
CREATE VIEW CS_grade_report AS
SELECT Student.student_id AS "ID",
student_name AS "Name",
course_number AS "Course #",
credit AS "Credit",
grade AS Grade
FROM Student, Class, Enrolls
WHERE major = 'CSCI'
AND Student.student_id = Enrolls.student_id
AND Class.schedule_num = Enrolls.schedule_num;
SELECT *
FROM CS_grade_report;
And this is what is generated:
ID Name Course # Credit GR
------ ------------------------- -------- ---------- --
600000 John Smith CSCI3200 4 B+
600000 John Smith CSCI3700 3 C
600000 John Smith SPAN1004 3 A-
600000 John Smith CSCI4300 3 A+
600001 Andrew Tram MUSC2406 2 A+
600001 Andrew Tram SPAN1004 3 A
600001 Andrew Tram CSCI3700 3 B-
600002 Jane Doe CSCI4200 3 D+
600003 Michael Jordan CSCI4300 3 A+
600004 Tiger Woods MUSC1000 1 A
600007 Dominique Davis CSCI4300 3 F
ID Name Course # Credit GR
------ ------------------------- -------- ---------- --
600009 Will Smith CSCI3200 4 A
600010 Papa Johns CSCI3200 4 B
600011 John Doe CSCI3200 4 C
600012 Jackie Chan CSCI3200 4 D
600013 Some Guy CSCI3200 4 E
16 rows selected.

I am assuming this is output from sqlplus. There is a "pagesize" option to define when breaks are added. If you only want to see one heading, set the size to a large enough value prior to running your SELECT statement as such:
set pagesize 500
(or whatever size you want)
There are many command options for sqlplus. This link is a good cheat-sheet.

Related

How to continue a sequence when inserting

I have tried to simplify my question with the following example:
I have a table with the following data:
Marker Name Location
1 Eric Benson Mixed
2 John Smith Rural
3 A David Rural
4 B John Mixed
And i want to insert into the table:
Name Location
Andy Jones Mixed
Ian Davies Rural
How can i continue the sequencein the Marker column to end up with:
Marker Name Location
1 Eric Benson Mixed
2 John Smith Rural
3 A David Rural
4 B John Mixed
5 Andy Jones Mixed
6 Ian Davies Rural
If you make this with a Stored Procedure you can ask the max of the Marker before to insert.
(That only works if the Marker Column is not identity)
Like This:
declare #max_marker int
set #max_marker=isnull((select max(marker) from table),0)
--Insert comes here
Insert into table (Marker,Name,Location) Values(#max_marker+1,'Andy Jones','Mixed')

How to populate field based on groupings?

I am trying to create a PowerShell (5.1) script (Open to SQL suggestions as well using SSMS with SQL Server 2014) to eliminate manual effort of updating a very large data file exported in CSV format.
Here is what the raw data set looks like that needs updated:
Parent ID | Parent Owner | Sub ID | Sub Owner | Sub Hours
A aA Rob Green 0
A aB Rob Green 6
B aA Jane Doe 4
B aB Jane Doe 10
B aC Bob Smith 18
C cA Jane Doe 0
C cB Jane Doe 6
D dA Bob Smith 0
D dB Bob Smith 6
E dE Joe Brown 0
As you can see, Parent IDs can have one or many Sub Owners and Sub IDs.
My goal is to populate the Parent Owner field based on the following criteria:
For every Parent ID set
If there is only one distinct Sub Owner, then that Sub Owner should be the Parent Owner for all corresponding Parent IDs.
If there is only one occurrence of a Parent ID then that Sub Owner should be the Parent Owner for that Parent ID.
If there are multiple Sub Owners for the Parent ID, the Sub Owner with the highest summed Sub Hours should be the Parent Owner for every occurrence of that Parent ID.
To clarify, the criteria applies to the raw data above like so:
Parent ID "A" applies to criteria 1
Parent ID "B" applies to criteria 3
Parent ID "C" applies to criteria 1
Parent ID "D" applies to criteria 1
Parent ID "E" applies to criteria 2
This is what I expect the data above to look like after completed:
Parent ID | Parent Owner | Sub ID | Sub Owner | Sub Hours
A Rob Green aA Rob Green 0
A Rob Green aB Rob Green 6
B Bob Smith aA Jane Doe 4
B Bob Smith aB Jane Doe 10
B Bob Smith aC Bob Smith 18
C Jane Doe cA Jane Doe 0
C Jane Doe cB Jane Doe 6
D Bob Smith dA Bob Smith 0
D Bob Smith dB Bob Smith 6
E Joe Brown dE Joe Brown 0
My biggest struggle is criteria 3. I cannot wrap my head around how to do this. Can anyone give me an idea of how I can get my expected output using PS or SQL?
Any help would be GREATLY appreciated!
I vowed myself that SQL is strictly taboo for me. However, below's an example of pure PowerShell solution (and I'm pretty sure that it's convertible to SQL simply):
# mimic SQL output
$SqlOutput = #"
Parent ID|Parent Owner|Sub ID|Sub Owner|Sub Hours
A||aA|Rob Green|0
A||aB|Rob Green|6
B||aA|Jane Doe|4
B||aB|Jane Doe|10
B||aC|Bob Smith|18
C||cA|Jane Doe|0
C||cB|Jane Doe|6
D||dA|Bob Smith|0
D||dB|Bob Smith|6
E||dE|Joe Brown|0
"# | ConvertFrom-Csv -Delimiter '|'
# compute an auxiliary variable
$SqlOutputGroups = $SqlOutput |
Group-Object -Property 'Parent ID', 'Sub Owner' |
ForEach-Object {
New-Object psobject -Property #{
'Parent ID' = ( $_.Name -split ', ')[0]
'Sub Owner' = ( $_.Name -split ', ')[1]
Hours = ( $_.Group |
Measure-Object -Property 'Sub Hours' -Sum).Sum
}
}
# compute Criterium3 as a hashtable
$SqlOutputCriterium3 = #{}
$SqlOutputGroups | Group-Object -Property 'Parent ID' |
ForEach-Object {
$SqlOutputCriterium3[$_.Name] = ($_.Group |
Sort-Object -Property Hours |
Select-Object -Last 1).'Sub Owner'
}
# apply Criterium3
$SqlOutput | ForEach-Object {
$_.'Parent Owner' = $SqlOutputCriterium3.$($_.'Parent ID')
}
# show result in a table format
$SqlOutput | Format-Table -AutoSize
Output: D:\PShell\SO\45963820.ps1
Parent ID Parent Owner Sub ID Sub Owner Sub Hours
--------- ------------ ------ --------- ---------
A Rob Green aA Rob Green 0
A Rob Green aB Rob Green 6
B Bob Smith aA Jane Doe 4
B Bob Smith aB Jane Doe 10
B Bob Smith aC Bob Smith 18
C Jane Doe cA Jane Doe 0
C Jane Doe cB Jane Doe 6
D Bob Smith dA Bob Smith 0
D Bob Smith dB Bob Smith 6
E Joe Brown dE Joe Brown 0
Note that Criterium 3 covers criteria 1 and 2 but does not suffice if more Sub Owners have the same highest sum of Sub Hours for a particular Parent ID (e.g in case of B||aA|Jane Doe|8 instead of B||aA|Jane Doe|4 in the above example, then Jane Doe has sum of Sub Hours =18 as well as Bob Smith in Parent ID=B).

SQL Sorting table based on two interchangeable fields

I want to sort a table having 3 columns (time, source , recipient) by the order by which communication is being made. If the source and recipient are conversing together then it will list them by the time. The goal is to see the communication happening between similar people ordered by time.An example is as:
time|source|recipient
1 paul amy
2 amy paul
3 amy paul
5 paul jane
8 amy paul
9 jane paul
10 paul amy
11 paul jane
the end result would be like
1 paul amy
2 amy paul
3 amy paul
8 amy paul
10 paul amy
5 paul jane
9 jane paul
11 paul jane
Your question is a bit vague. My educated guess is you want this:
SELECT *
FROM tbl
ORDER BY (GREATEST(source, recipient), LEAST(source, recipient), "time";
The manual about GREATEST and LEAST.

Using multiple inner joins and sorting result

In my DB there are three tables. I am trying to figure out how to List the school name, class name and teacher's name. Sort the records by class name within school name. I have a query but it is not working. How can I list the school name, class name and teacher's name and sort record by class name within school name?
SELECT c.class_name FROM class c INNER JOIN teacher t WHERE t.teacher_id = c.teacher_id INNER JOIN school s WHERE t.school_id = s.school_id;
TABLES
SQL> select * from class;
CLASS_ID CLASS_NAME TEACHER_ID MAX_SEATS_AVAILABLE
---------- ------------------- ---------- -------------------
1 Intro to ALGEBRA 11 12
2 Basic CALCULUS 2 10
3 ABC and 123 1 15
4 Sharing 101 8 10
5 Good Talk, Bad Talk 9 20
6 Nap Time 1 21
7 WRITing 101 5 10
8 Finger Painting 9 14
9 Physics 230 2 20
10 Gym 5 25
10 rows selected.
SQL> select * from teacher;
TEACHER_ID FIRST_NAME LAST_NAME T HOME_ROOM_NUM PHONE_NUM START_DAT HO SCHOOL_ID
---------- ---------------- ---------------- - ------------- ---------- --------- -- ----------
1 FRanK JOHNSON k 10C 22-OCT-97 In 11090
2 LISA JONES h 11Bc 317-587-90 19-JAN-15 iN 123134
87
3 Jeff Dafferty C W8CZ 12-DEC-96 OH 11546
4 Frank MARTIN g 12aA 212-098-98 19-JAN-15 IN 11090
76
5 John Smith H 34C 10-OCT-93 In 123134
6 John Smith G 34C 10-OCT-93 in 11090
7 Lisa Jones G 11E 317-587-90 19-JAN-15 IN 123134
87
8 Trevor Horse k x 19-JAN-15 Oh 11090
9 Gregor Ivan K 12A 317-987-09 10-NOV-96 KY 11090
87
10 Gregor Ivan g 12A 317-987-09 10-NOV-96 Ky 11090
87
11 Pat Francis H 1z1a 123-317-09 19-JAN-15 Il 11546
12
12 Brad Smith G 13A 18-NOV-94 IN 11546
12 rows selected.
SQL> select * from school;
SCHOOL_ID SCHOOL_NAME SCHOOL_TYPE
---------- ----------------------------- ------------
11546 Ivy Tech College COLLegE
11090 LAWRENCE Central Grade School GRADE SCHOOL
11111 Lawrence NORTH High School HIGH SCHooL
19283 Howe High SCHOOL High SchooL
123134 Lawrence Central High School HIGH SCHOOL
192 Little Big Horn Grade School GRADE SCHOOL
You can use the join to get what you want. This will give the all schools with the teachers and there classes.
SELECT DISTINCT
sc.SCHOOL_NAME,
teach.FIRST_NAME,
teach.LAST_NAME ,
cs.CLASS_NAME
FROM
school sc JOIN teacher teach
ON sc.SCHOOL_ID = teach.SCHOOL_ID
JOIN class cs ON cs.TEACHER_ID = teach.TEACHER_ID
ORDER BY
sc.SCHOOL_NAME,cs.CLASS_NAME
SELECT t.FIRST_NAME +' '+t.LAST_NAME, s.SCHOOL_NAME, c.class_name
FROM class c
INNER JOIN teacher t
ON t.teacher_id = c.teacher_id
INNER JOIN school s
ON t.school_id = s.school_id
ORDER BY s.SCHOOL_NAME,c.CLASS_NAME

VBA/SQL recordsets

The project I'm asking about is for sending an email to teachers asking what books they're using for the classes they're teaching next semester, so that the books can be ordered. I have a query that compares the course number of this upcoming semester's classes to the course numbers of historical textbook orders, pulling out only those classes that are being taught this semester. That's where I get lost.
I have a table that contains the following:
Professor
Course Number
Year
Book Title
The data looks like this:
professor year course number title
--------- ---- ------------- -------------------
smith 13 1111 Pride and Prejudice
smith 13 1111 The Fountainhead
smith 13 1222 The Alchemist
smith 12 1111 Pride and Prejudice
smith 11 1222 Infinite Jest
smith 10 1333 The Bible
smith 13 1333 The Bible
smith 12 1222 The Alchemist
smith 10 1111 Moby Dick
johnson 12 1222 The Tipping Point
johnson 11 1333 Anna Kerenina
johnson 10 1333 Everything is Illuminated
johnson 12 1222 The Savage Detectives
johnson 11 1333 In Search of Lost Time
johnson 10 1333 Great Expectations
johnson 9 1222 Proust on the Shore
Here's what I need the code to do "on paper":
Group the records by professor. Determine every unique course number in that group, and group records by course number. For each unique course number, determine the highest year associated. Then spit out every record with that professor+course number+year combination.
With the sample data, the results would be:
professor year course number title
--------- ---- ------------- -------------------
smith 13 1111 Pride and Prejudice
smith 13 1111 The Fountainhead
smith 13 1222 The Alchemist
smith 13 1333 The Bible
johnson 12 1222 The Tipping Point
johnson 11 1333 Anna Kerenina
johnson 12 1222 The Savage Detectives
johnson 11 1333 In Search of Lost Time
I'm thinking I should make a record set for each teacher, and within that, another record set for each course number. Within the course number record set, I need the system to determine what the highest year number is - maybe store that in a variable? Then pull out every associated record so that if the teacher ordered 3 books the last time they taught that class (whether it was in 2013 or 2012 and so on) all three books display. I'm not sure I'm thinking of record sets in the right way, though.
My SQL so far is basic and clearly doesn't work:
SELECT [All].Professor, [All].Course, Max([All].Year)
FROM [All]
GROUP BY [All].Professor, [All].Course;
Use your query as a subquery and INNER JOIN it back to the [ALL] table to filter the rows.
SELECT
a.Professor,
a.Year,
a.Course,
a.title
FROM
[ALL] AS a
INNER JOIN
(
SELECT [All].Professor, [All].Course, Max([All].Year) AS MaxOfYear
FROM [All]
GROUP BY [All].Professor, [All].Course
) AS sub
ON
a.Professor = sub.Professor
AND a.Course = sub.Course
AND a.Year = sub.MaxOfYear;