I'm having trouble creating a view for one of my MYSQL assignments. I understand how to create a view technically, as in, the commands to do so. (I have already done a few other different views for this assignment) My problem is with how to design this particular view... I don't know how to with the knowledge I have/The way I designed my tables.
So, I have 2 relevant tables(There are 2 others but I don't think they are needed for this problem): Attendance and Scholar. I need to create a view where all scholars are listed as well as the date where they were an invited speaker. However, if they were never an Invited Speaker, the date should have a null value shown. So I need to select First Name and LastName from Scholar and ADate from Attendance. Attendance has the column AttendanceType that can be either Invited Speaker or Chairman. Attendance also has the foreign key LName, relating to LastName, and ADate obviously. I can't conceptually think of have to do this, I thought that using a join, which I'm not that experienced with would be the right choice but it didn't work...
Here's what I attempted
CREATE VIEW InvitedScholars
AS SELECT FirstName,LastName,ADate
FROM Scholar LEFT JOIN Attendance ON AttendanceType='Invited Speaker'
WHERE Lname=LastName;
This only gave me Invited Speakers, not all Scholars... I don't know how to progress... any advice would be appreciated.
You need to do your left join on the Last Name (assuming this is your key on both tables). See the SQL below:
CREATE VIEW InvitedScholars
AS SELECT FirstName,LastName,ADate
FROM Scholar LEFT JOIN Attendance ON Scholar.LastName = Attendance.LName
AND Attendance.AttendanceType = 'Invited Speaker';
It appears you have your join and where clauses mixed up. You want to join the the two tables on the last name (which invites another issue if you have two speakers with the same last name) and filter by AttendanceType
FROM Scholar LEFT JOIN Attendance ON Lname=LastName
WHERE AttendanceType='Invited Speaker'
Related
Hi I have run in to a problem when retrieving a particular data set using 3 tables in a MySql database.Tables are as follows
Student
SID | Name | Age | Telephone
Term
TID | Start | End
Payment
PID | TID | SID | Value
SID is primary key of Student table. TID is primary key of Term table. PID is primary key of Payment table. TID and SID in Payment table are foreign key references.
Student table contains data of students. Term table contain data of term start and end dates. Payment table contain data about student payment. Records in Payment table may either contain TID or not. When it is a registration payment there will be no TID. Otherwise it is a term fee and there will be TID. What I want is a list of students that hasn't paid this terms fees until today. Asuume this TID is in a variable. How can I obtain the list of students ? IT SEEMS SUPER EASY. BUT I COULDNT FIND AN ANSWER THIS WHOLE DAY 😣
You want a list of just those students who do not have a TID-populated record whose start and end dates are either side of today, in Payment
SELECT * FROM
student
LEFT OUTER JOIN
(select * from payment where TID is not null and NOW() BETWEEN start and end) this_term_payments
on student.id = this_term_payments.sid
WHERE
this_term_payments.ID is null
There are many ways to skin this cat. Here is one. We filter the payments table down to just a list of this term's payments (that's the inner query). And left join that to students. Left join means we get all students, matched with this_term_payments if the this_term_payments row exists, or NULL in every this_term_payments column if the term payment doesn't exist. The where clause then filters the whole results set down to "just those who don't have a term payment" by looking for those nulls that the left join creates
FWIW, your question attracted close votes because it didn't include example data/demonstrate the level of your effort we like to see on SQL questions. If you'd included sample data for all your tables and an example result set you wanted to see out, it means we can write an exact query that meets your requirements.
This is a bit of a double edged sword for me; we can deliver exactly what you ask for even if you later realise it's not what you want (asking in English is far more vague than giving an example result set) but at the same time we basically become some free outsourced homework contractor or similar, doing your work for you and removing learning opportunities along the way. Hopefully you'll take this query (it's likely it doesn't output everything you want, or outputs stuff you don't want) and craft what you want out of it now that the technique has been explained.. :)
For an SQL question that was relatively well received (by the time i'd finished editing it following up on the comments), and attracted some great answers take a look here:
Fill in gaps in data, using a value proportional to the gap distance to data from the surrounding rows?
That's more how you need to be asking SQL questions - say what you want, give example data, give scripts to help people create your same data so they can have a play with their idea without the boring bits of creating the data first. I picked on that one because I didn't even have any SQL attempts to show at the time; it was just a thought exercise. Having nothing working isn't necessarily a barrier to asking a good question
Try this:
select s.name, p.value from Student s, Term t, Payment p where t.TID = p.TID and s.SID=p.SID and p.TID is null;
Suppose I have a database called clubmembership that has a column for names, a column for clubs, and a column for the role they play in that club. The name Margrit would be in the column name many times, or as many times as she is in a club. If I want to see which people are members of the sewing club my query might look something like this:
SELECT DISTINCT NAME FROM CLUBMEMBERSHIP
WHERE CLUB=’SEWING’
AND ROLE=’MEMBER’;
My problem is that I can't figure out a query for who is not in the sewing club. Of course the simple 'not in' clause isn't working because there are plenty of rows which sewing does not appear in. In this database if someone is not in the sewing club, sewing does not appear under club so I imagine there is a way to join the different rows with the same name under 'name' and then potentially use the 'not in' clause
I hope this was a good explanation of this question. I have been struggling with this problem for a while now.
Thanks for your help!
Nicolle
This is not something that can be solved by just changing the existing code, it is to do with the database design.
Database normalisation is the process of sorting out your database into sensible tables.
If you’re adding a person many times, then you should create a table called members instead. And if there is a list of clubs, then you should create a clubs table.
Then, you can create a table to join them together.
Here’s your three tables:
members
-------
id (int)
name (varchar)
clubs
-------
id (int)
name (varchar)
memberships
-------
member_id (int)
club_id (int)
Then you can use joins in MySQL to return the information you need.
Stack Overflow doesn’t like external links as the answer should be here, but this is a huge topic that won’t fit in a single reply, so I would briefly read about database normalization, and then read about ‘joining’ tables.
If I understand you correctly, you wanted to list all names that is not a member of SEWING. The Inner query will get all Names that are member of SEWING, however, the NOT EXISTS operator will get all Names that are not found in the inner query.
SELECT DISTINCT C.NAME
FROM CLUBMEMBERSHIP C
WHERE C.ROLE = 'MEMBER'
NOT EXISTS
(
SELECT NULL
FROM CLUBMEMBERSHIP D
WHERE D.CLUB='SEWING'
AND D.ROLE='MEMBER'
AND C.NAME = D.NAME
)
Here's a Demo.
I am pretty new to MS Access and a bit at a loss. I am also not very familiar with database jargon, so bear with me.
I have a table with staff names in it (each an individual record and staffID).
I have another table with a log, each entry shows at what time a particular staffID took a particular course (course names are stored in another table).
Now I want to make a report that lists each course and the names of the people, who took it.
How do I do that?
You need to learn about database joins. Its a fundamental requirement for what you are doing.
SELECT * FROM stafftable s INNER JOIN logtable l ON l.staffID = s.staffID
will give you a virtual table listing staff details and the course they were on.
You can do this multiple times - so you say the course data is in another table
SELECT s.name As StaffName, c.name As CourseName FROM stafftables INNER JOIN (logtable l INNER JOIN coursetable c ON l.courseID = c.courseID) ON l.staffID = s.staffID
Will give you a two column table with StaffName and CourseName as the two columns. Note: Access is picky about these joins and you have to put them in brackets like this. Other databases you normally don't have to.
I think the report wizard could solve your problem.
The wizard walks you through the steps of creating a report and will allow you the opportunity to use more than one table/query in the report.
Since you are looking to group by the course, all you would need to do is tell the wizard to do that when it asks you.
This is a straight forward guide on how to use the report wizard: report wizard guide
Im not sure how to exactly word my issue but I will try my best. Im trying to model a database for a driving school. I have a "timeslot" table such that activities such as lessons, tests, and registration interviews can all be linked to a given timeslot for a staff member. One of the queries I am providing is to be able to view a "timetable" of events for a staff member. I have constructed the query and it is working, however it joins data from various other tables, and I would like to see the names of those tables to know what activity the timeslot is reserved for.
ER Model
The query I perform to check the staff timetable is the following:
SELECT Timeslot.*
FROM Timeslot
LEFT JOIN Test
ON Timeslot.Timeslot_ID = Test.Timeslot
LEFT JOIN Interview
ON Timeslot.Timeslot_ID = Interview.Timeslot
LEFT JOIN Lesson
ON Timeslot.Timeslot_ID = Lesson.Timeslot
WHERE Timeslot.Date BETWEEN CURDATE() AND (CURDATE() + INTERVAL 7 DAY)
AND Timeslot.Staff = 1;
This works and shows a list of all registered timeslots for a given staff member for the next week. What I would like is a further column which would show what type of activity it is, such as "Lesson", "Interview", or "Test". As you can see, I am currently storing this as a field in the timeslot table, which means that I have to specify this every time I insert a timeslot. I will be normalising the database to 3NF and want to avoid duplication. Is there a way I model this to get the name of the table, I considered using UNIONS and many other things but could use some help.
Many thanks and apologies if this seems a bit vague.
Mike
My stab at it, if you're keeping the model you've described, would be with a Case statement, like so:
Select Timeslot.*,
Case
When Test.Timeslot Is Not Null Then 'Test'
When Interview.Timeslot Is Not Null Then 'Interview'
When Lesson.Timeslot Is Not Null Then 'Lesson'
End As ActivityType
From ...
Your query would then have an "ActivityType" column at the very end that you could use.
I have a table with the following fields (for example);
id, reference, customerId.
Now, I often want to log an enquiry for a customer.. BUT, in some cases, I need to filter the enquiry based on the customers country... which is in the customer table..
id, Name, Country..for example
At the moment, my application shows 15 enquiries per page and I am SELECTing all enquiries, and for each one, checking the country field in customerTable based on the customerId to filter the country. I would also count the number of enquiries this way to find out the total number of enquiries and be able to display the page (Page 1 of 4).
As the database is growing, I am starting to notice a bit of lag, and I think my methodology is a bit flawed!
My first guess at how this should be done, is I can add the country to the enquiryTable. Problem solved, but does anyone else have a suggestion as to how this might be done? Because I don't like the idea of having to update each enquiry every time the country of a contact is changed.
Thanks in advance!
It looks to me like this data should be spread over 3 tables
customers
enquiries
countries
Then by using joins you can bring out the customer and country data and filter by either. Something like.....
SELECT
enquiries.enquiryid,
enquiries.enquiredetails,
customers.customerid,
customers.reference,
customers.countryid,
countries.name AS countryname
FROM
enquiries
INNER JOIN customers ON enquiries.customerid = customers.customerid
INNER JOIN countries ON customers.countryid = countries.countryid
WHERE countries.name='United Kingdom'
You should definitely be only touching the database once to do this.
Depending on how you are accessing your data you may be able to get a row count without issuing a second COUNT(*) query. You havent mentioned what programming language or data access strategy you have so difficult to be more helpful with the count. If you have no easy way of determining row count from within the data access layer of your code then you could use a stored procedure with an output parameter to give you the row count without making two round trips to the database. It all depends on your architecture, data access strategy and how close you are to your database.