Query Prompting for Parameter Value - ms-access

I am attempting to creat a VIEW for my class. I was instructed to make my Access Compatible syntax ANSI 92. I have done that but I keep getting a message saying to:
"Enter parameter Value for 'JR'."
But it should just be showing any with the JR in the field value.
Any idea what I am doing wrong?
SELECT Student.IDno, LastName, FirstName, Class AS
Junior, Major, GPA
FROM Student, Person
WHERE Student.IDno = Person.IDno
AND Class = “JR”;
I also have to include columns from 2-3 different tables, change the titles of two of the columns, and show only the records that have class = "JR".
Any advice on where to start looking for this info would be great.
Thank you.
EDIT: Thank you for the help with that last one. Now I'm trying to change this to be able to pull from multiple tables and I can't seem to figure anything out. When I run this code, it tells me it can't find the table or query. If I run each section alone, it works just fine. I need to pull some info from 4 tables...
SELECT Student.IDno, Person.LastName, Person.FirstName, Student.Class, Student.Major, Student.GPA
FROM Student, Person
WHERE Student.IDno = Person.IDno
AND Class = 'JR';
UNION
SELECT Student.IDno, Enrollment.OfferNo, Enrollment.Grade
FROM Student, Enrollment
WHERE Student.IDno = Enrollment.IDno;

The double-quotes present in your SQL code are 'smart quotes' or Unicode character 0x201C, as opposed to the standard double-quote, which is Unicode/ASCII character 0x0022.
Hence changing the SQL to either:
SELECT Student.IDno, LastName, FirstName, Class AS Junior, Major, GPA
FROM Student, Person
WHERE Student.IDno = Person.IDno
AND Class = "JR";
or:
SELECT Student.IDno, LastName, FirstName, Class AS Junior, Major, GPA
FROM Student, Person
WHERE Student.IDno = Person.IDno
AND Class = 'JR';
Will solve this.
However, I would also strongly suggest using an INNER JOIN (i.e. ANSI-92 syntax) in place of a cartesian product with join criteria in the WHERE clause (ANSI-89 syntax):
SELECT Student.IDno, LastName, FirstName, Class AS Junior, Major, GPA
FROM Student INNER JOIN Person ON Student.IDno = Person.IDno
WHERE Class = 'JR';
It is also advisable to state the table qualifier for each field (e.g. Person.LastName or Student.LastName) so as to avoid the improper use of reserved words or ambiguity arising from identically named fields in multiple tables.
In the code you have added to your question, you are attempting to UNION two SELECT queries which output a different number of columns, and presumably, different data types - this is invalid.
I imagine that you are actually looking to do this:
select
student.idno,
person.lastname,
person.firstname,
student.class,
student.major,
student.gpa,
enrollment.offerno,
enrollment.grade
from
(
student inner join person
on student.idno = person.idno
)
inner join enrollment
on student.idno = enrollment.idno
where
student.class = 'JR'

Related

SQL Checking if a value exists in any column and return the value listed of another column

I'm trying to figure out how I can run a query to check and see if someone is listed under someone else. An example would be like a team. There is a team leader and people under that leader. I need to run a query to see if a name is listed under someone else.
I have a table with the following columns:
ID;
Leader_FirstName;
Leader_LastName;
Member1_FN;
Member1_LN;
Member2_FN;
Member2_LN, etc...
I need to check the whole table and if that name exist as any of the members it would return the value of Leader_FirstName and Leader_LastName.
I've been trying to use a "WHERE EXISTS" Like:
SELECT * FROM team
WHERE EXISTS (SELECT * FROM team
WHERE Member1_FN = '$member_fName' AND Member1_LN = '$member_lName'
OR Member2_FN = '$member_fName' AND Member2_LN = '$member_lName'
OR ... etc...
)
Any ideas?
In my opinion, for this data model, one row records one leader and all members, there is no good way to query it.
SELECT * FROM team
WHERE (Member1_FN = '$member_fName' AND Member1_LN = '$member_lName')
OR (Member2_FN = '$member_fName' AND Member2_LN = '$member_lName')
OR (... etc...
This is equivalent to your SQL, but not good.
I think, this table structure is unreasonable. The number of columns in the table depends on the maximum number of members of the leader. If add some members, you must change the table structure to add some columns. It is not flexible enough.
There are many methods to optimize the structure.
1. One row with one member
Table team with the following columns:
ID
Leader_FirstName
Leader_LastName
Member_FN
Member_LN
Leader info will record at many rows, this is the major disadvantage for this structure. In order to avoid this problem, you can try follow method.
2. Two tables: leader and member
Table leader with following columns:
ID
FirstName
LastName
Table member with following columns:
ID
FirstName
LastName
LeaderID
Now, you can join leader and member to find the leader of members.
3. One table team with relationship
Table team is same with the member as follow:
ID
FirstName
LastName
LeaderID (For leader is NULL)
Now, join team and itself.
Use above structure, how to query? I think, you can concat the FirstName and LastName with an separator char that does not appear in the name to a string, than use IN to compare it, for example:
For 1:
SELECT *
FROM team
WHERE CONCAT_WS(',', Member_FN, Member_LN)
IN (CONCAT_WS(',', '$member1_fName', '$member1_fName'),
CONCAT_WS(',', '$member2_fName', '$member2_fName'),
...etc...)
For 2:
SELECT *
FROM leader, member
WHERE leader.ID = member.LeaderId and CONCAT_WS(',', member.FirstName, member.LastName)
IN (CONCAT_WS(',', '$member1_fName', '$member1_fName'),
CONCAT_WS(',', '$member2_fName', '$member2_fName'),
...etc...)
For 3:
SELECT *
FROM team a, team b
WHERE a.ID = b.LeaderId and CONCAT_WS(',', b.FirstName, b.LastName)
IN (CONCAT_WS(',', '$member1_fName', '$member1_fName'),
CONCAT_WS(',', '$member2_fName', '$member2_fName'),
...etc...)
try this
SELECT * FROM team
WHERE (Member1_FN = '$member_fName' AND Member1_LN = '$member_lName')
OR (Member2_FN = '$member_fName' AND Member2_LN = '$member_lName')
OR (... etc...

SQL Query outputting "yes"

I'm studying for my Database System exam tomorrow, and I'm working on an SQL question. This question is the only one from the paper that doesn't have an answer, but here's the question:
We use the following schema:
Professor(name, office, dept, age) (age is key)
Course(cno, title, dept) (cno stands for course number and is a key, title is the name of the course and dept is name of department offering the course)
Enrollment(cno, semester, inst_name, enrollment) (the key for this is (cno, semester)
Question: Write the following sql query: Output a table containing the single row "yes" in it if the age difference between the oldest and the youngest professors teaching the Database Systems course between 2000 and 2009 is at most 5 years
I amn't sure my approach is right, since we don't exactly want to output something from the table. Note that I think enrollment corresponds to when the instructor started teaching the course (which isn't the usual definition AFAIK).
My approach is as follows:
WITH dbsProfs AS (
SELECT P.age
FROM Professor P, Enroll E, Course C
WHERE P.name = E.inst_name AND C.cno = E.cno AND C.title = "Database Systems"
AND E.enrollment BETWEEN 2000 and 2009
)
SELECT "Yes"
FROM dbsProfs
WHERE MAX(dbsProfs.age) - MIN(dbsProfs.age) <= 5
I'm fairly confident with my temporary table. I'm doing a join on all 3 tables and filtering out to include only the ones relevant to my query. It's the other half I'm unsure about.
Any insight on whether this is correct/how to correct this would be much appreciated. I amn't convinced WHERE MAX(dbsProfs.age) - MIN(dbsProfs.age) <= 5 is valid SQL
With aggregate function you shoud use having
SELECT "Yes"
FROM dbsProfs
HAVING MAX(dbsProfs.age) - MIN(dbsProfs.age) <= 5
WITH dbsProfs AS (
SELECT MIN(P.age) as min_age,MAX(P.age) as max_age
FROM Professor P, Enroll E, Course C
WHERE P.name = E.inst_name AND C.cno = E.cno AND C.title = "Database Systems"
AND E.enrollment BETWEEN 2000 and 2009
)
SELECT CASE WHEN min_age<max_age THEN "Yes" END
FROM dbsProfs
It's true, you can't put aggregate functions in your WHERE statement. This question will take a bit more work.
This is the approach I would take:
SELECT CASE WHEN A.MaxAge - A.MinAge <=5 THEN "Yes" END
FROM
(
SELECT Max(Professor.age) AS MaxAge, Min(Professor.age) AS MinAge
FROM Professor INNER JOIN Enroll ON Professor.name = Enroll.inst_name
INNER JOIN Course ON Enroll.cno = Course.cno
WHERE Course.title = "Database Systems" AND Enroll.enrollment BETWEEN 2000 AND 2009
) AS A
This assumes enrollment is indeed the year the course was instructed (as you also assumed). You can use an iif statement if you're fond of SQL Server instead of the SELECT CASE (the latter being more t-SQL standards friendly).

Django querysets: Excluding NULL values across multiple joins

I'm trying to avoid using extra() here, but haven't found a way to get the results I want using Django's other queryset methods.
My models relationships are as follows:
Model: Enrollment
FK to Course
FK to User
FK to Mentor (can be NULL)
Model: Course
FK to CourseType
In a single query: given a User, I'm trying to get all of the CourseTypes they have access to. A User has access to a CourseType if they have an Enrollment with both a Course of that CourseType AND an existing Mentor.
This user has 2 Enrollments: one in a Course for CourseType ID 6, and the other for a Course for CourseType ID 7, but her enrollment for CourseType ID 7 does not have a mentor, so she does not have access to CourseType ID 7.
user = User.objects.get(pk=123)
This works fine: Get all of the CourseTypes that the user has enrollments for, but don't (yet) query for the mentor requirement:
In [28]: CourseType.objects.filter(course__enrollment__user=user).values('pk')
Out[28]: [{'pk': 6L}, {'pk': 7L}]
This does not give me the result I want: Excluding enrollments with NULL mentor values. I want it to return only ID 6 since that is the only enrollment with a mentor, but it returns an empty queryset:
In [29]: CourseType.objects.filter(course__enrollment__user=user).exclude(course__enrollment__mentor=None).values('pk')
Out[29]: []
Here's the generated SQL for the last queryset that isn't returning what I want it to:
SELECT `courses_coursetype`.`id` FROM `courses_coursetype` INNER JOIN `courses_course` ON ( `courses_coursetype`.`id` = `courses_course`.`course_type_id` ) INNER JOIN `store_enrollment` ON ( `courses_course`.`id` = `store_enrollment`.`course_id` ) WHERE (`store_enrollment`.`user_id` = 3877 AND NOT (`courses_coursetype`.`id` IN (SELECT U0.`id` AS `id` FROM `courses_coursetype` U0 LEFT OUTER JOIN `courses_course` U1 ON ( U0.`id` = U1.`course_type_id` ) LEFT OUTER JOIN `store_enrollment` U2 ON ( U1.`id` = U2.`course_id` ) WHERE U2.`mentor_id` IS NULL)))
The problem, it seems, is that in implementing the exclude(), Django is creating a subquery which is excluding more rows than I want excluded.
To get the desired results, I had to use extra() to explicitly exclude NULL Mentor values in the WHERE clause:
In [36]: CourseType.objects.filter(course__enrollment__user=user).extra(where=['store_enrollment.mentor_id IS NOT NULL']).values('pk')
Out[36]: [{'pk': 6L}]
Is there a way to get this result without using extra()? If not, should I file a ticket with Django per the docs? I looked at the existing tickets and searched for this issue but unfortunately came up short.
I'm using Django 1.7.10 with MySQL.
Thanks!
Try using isnull.
CourseType.objects.filter(
course__enrollment__user=user,
course__enrollment__mentor__isnull=False,
).values('pk')
Instead of exclude() you can create complex queries using Q(), or in your case ~Q():
filter_q = Q(course__enrollment__user=user) | ~Q(course__enrollment__mentor=None)
CourseType.objects.filter(filter_q).values('pk')
This might lead to a different SQL statement.
See docs:
https://docs.djangoproject.com/en/3.2/topics/db/queries/#complex-lookups-with-q-objects

SQL Subqueries Issue

I'm trying to do an assignment for my course where one of the questions is to get the faculty name, date hired (in dd-mon-yyyy format) and that have the same title as Erit Jackson in the database, who's title is Assoc Prof. My code looks identical to the example provided by the instructor, but when I run this code, I get the error:
2014 - Commands out of sync; you can't run this command now
I don't know what I'm doing wrong thus far?
SELECT CONCAT('Dr.', ' ', LName) As 'Faculty Name', DateHired
FROM Faculty
WHERE Title = (
SELECT Title
FROM Faculty
WHERE Title = 'Assoc Prof');
This doesn't make a lot of sense as written. It can be simplified:
SELECT CONCAT('Dr.', ' ', f1.LName) As 'Faculty Name', f1.DateHired
FROM Faculty f1
INNER JOIN Faculty f2
ON f1.Title = f2.Title
WHERE f2.FName = 'Erit'
AND f2.LName = 'Jackson';
The way you are using the subquery is redundant. You're asking the database for the person that has the title(select & from), that matches(where title =) a table of titles with the title of 'Assoc Prof'(subquery).
Your professor wants your subquery to find the title of Erit Jackson, not to specifically find the title "Assoc Prof". Do you see the difference? You won't ever have the text "Assoc Prof" in your query at all.

where clause in COUNT function and joining two queries

I have a table that I am trying to count the number of course passed, and also list the modules passed as well.
The first problem I am having is what to put in the where variable, so that its not specific to a customer(I can use the query below for a particular customer and a particular course)but I will like a generic query where the result will be distinct in terms of user and course like the one below
SELECT FirstName
,LastName
,CourseTitle
,Noofmodules
,count(Coursecompleted) AS modulescompleted
FROM EStudentsprogress
WHERE Coursecompleted = '1'
AND EmailAddress = 'scascsc#e.co.uk'
AND CourseTitle = 'Microsoft MOS 2010 EXCEL'
GROUP BY FirstName
,LastName
,CourseTitle
,Noofmodules
How can I make it list the result as above, whereby I don't specify the email address or course title(trying to get the result for all the clients )
Also I have a query that list the courses that is passed by the customer, I will like the column with the list of courses passed be added to the result above, but as a column for each course.
SELECT FirstName
,LastName
,CourseTitle
,EmailAddress
,CourseModule AS coursepassed
FROM EStudentsprogress
WHERE coursecompleted = 1
Cheers
Can you not just add the email address and course title fields to the select fields and the GROUP BY clause.
Also you can use GROUP_CONCAT to bring back a field containing all the course modules.
Something like this:-
SELECT FirstName,
LastName,
CourseTitle,
Noofmodules,
EmailAddress,
CourseTitlecount,
COUNT(Coursecompleted) as modulescompleted,
GROUP_CONCAT(CourseModule) as modulescompletednames
FROM EStudentsprogress
WHERE Coursecompleted = '1'
GROUP BY FirstName, LastName, CourseTitle, Noofmodules, EmailAddress, CourseTitlecount ;