SELECT C1.CERT_ANNOUNCEMENT
FROM EMPLOYEE C1, TEACHER C1, TEACHER_CERT_INT C1, CERTIFICATION C1
ORDER BY EMP_LNAME, EMP_FNAME;
Write a query and save it as a view to create announcement text for all teachers in the database that have
obtained certifications. The attribute you create should be named as below and the string you create must look
exactly as in the solution for full credit. Order by last name then first name.
It is supposed to be named CERT_ANNOUNCEMENT but this is not an attribute in the ER DIAGRAM.
Don't know how to create it exactly because when I run this it say invalid identifier. Any help is appreciated.
You should use unique alias for each table and use on clause to do joins and avoid full cartesian product, and also elaborate better your questions on SO.
The assignment asks you to create a view so you need to use the CREATE VIEW syntax.
The view uses data from several tables. You need to use join conditions to ensure that records are linked meaningfully. This usually means joining primary keys to foreign keys.
Give each table a unique alias to avoid compilation errors.
The view is supposed to show a message for all the teachers who have been awarded certificates. You need to form this announcement by concatenating columns from the tables with boilerplate text. Give this message a column alias of cert_announcement.
You not have posted any table structures so I have guessed what your tables' columns are called. Likewise the actual text of the announcement. So you need to figure out the precise details for yourself. At least that way you'll have earned some of the marks you'll get.
create or replace view full_credit_please as
select 'Teacher '
||emp.emp_fname||' '||emp.emp_lname
||' was awarded '||cert.certifcate_name
||' on '|| to_char(cert.award_date, 'DD-MON-YYYY')
as cert_announcement
from employee emp
join teacher tch
on tch.emp_id = emp.emp_id
join teacher_cert_int tc
on tc.tch_id = tch.tch_id
join certification cert
on cert.cert_id = tc.cert_id
order by emp.emp_lname, emp.emp_fname;
Related
(This is a general SQL question, but I am specifically using MSAccess 2010 so looking for how to do this with Access' flavor of SQL)
I have a table called offices which has id, office_name, num_desks.
Another table called employees which has id, employee_name.
And a final table called employee_offices which has id, office_id, employee_id.
I can assign employees to offices via employee_offices.
I am trying to generate a report which shows all offices and the employees assigned to the, but also includes blank lines for any empty desks in that office.
I realize a "simple" way to do this would be to create a desks table with id, office_id, delete the num_desks column from the offices table and change employee_offices to something like employee_desks. Then my report would be a simple LEFT OUTER JOIN and it would include all the unassigned desks. However for the sake of sanity (in this case, there is no contextual difference between desks), I am not going to do this. Plus if I start deleting desks I have referential constraints to deal with (which obviously exist for a good reason and would catch the fact that I am leaving employees without a desk), but I just want to be able to change the number of desks.
I can calculate the number of empty desks (or lack of desks) through the following command:
SELECT
office_id,
num_desks - num_employees AS desk_diff,
MAX(0, num_desks - num_employees) AS blank_rows_to_add
FROM offices LEFT OUTER JOIN (
SELECT office_id, COUNT(employee_id) AS num_employees
FROM employee_offices
GROUP BY office_Id
) AS num_employees_by_office ON offices.id = num_employees_by_office.office_id
Is there a way to take this number (blank_rows_to_add) and somehow utilze it to add that many blank rows (or at least the row only has the office_id/office_name) to a report showing a list of employees by office? I know this can be done with VBA but I am specifically looking for an SQL method that also doesn't include a temp table if at all possible.
Thank you.
I need to brind a lot of columns from several tables using LEFT JOIN. My starting point is the orders table and I bring the vendor name from the "Address_table". Then I add another table with order details and then the shipping information of each order detail.
My problem is that I need to bring a different record from "Address_table" to refer onether id's detailed in shipment table as of "origin_id" and "destination_id".
In other words, "address_id", "origin_id" and "destination_id" are all records from "Address_table". I brought the first one related to the vendor, how can I retrieve the other two?
Example
Thanks in advance
Your question is not exactly clear in terms of the tables and their relationships. It is, however, clear what the problem is. You need to join against the same table twice using different columns.
In order to do that you need to use table aliases. For example, you can do:
select *
from shipment s
left join address_table a on a.address_id = s.origin_id
left join address_table b on b.address_id = s.destination_id
In this example the table address_table is joined twice against the table shipment; the first time we use a as an alias, the second time b. This way you can differentiate how to pick the right columns and make the joins work as you need them to.
So I have looked into why this error occurs but I couldn't find any helpful answer. One person answered for another question that its because in the sql statement, the column name used for multiple tables may be the same. However, I tried to change that and yet I got the same error. Here is my sql statement:-
SELECT CLASSID INTO V_ID FROM CLASSES INNER JOIN BOOKING ON BOOKING.CLASSID=CLASSES.CLASSID WHERE BOOKING.BOOKINGID=:NEW.BOOKING_ID;
What did I do wrong?
SELECT
Bo.CLASSID INTO V_ID
FROM CLASSES cl INNER JOIN BOOKING bo ON
BO.CLASSID=Cl.CLASSID WHERE
BO.BOOKINGID=:NEWBOOKING_ID;
Try this. Your classid column exist in both tables. You have to explicitly choose classid column of which table you want select. In your select list in place of classid you should write booking.classid or classess.classid.
I added alias for table names. Bo for booking and cl for classess. This helps make code more compact. And in place of table name i have written alias name.
May be :
SELECT BOOKING.CLASSID INTO V_ID FROM CLASSES INNER JOIN BOOKING ON BOOKING.CLASSID=CLASSES.CLASSID WHERE BOOKING.BOOKINGID=:NEW.BOOKING_ID
This is part of my SQL homework and I can't wrap my head around it. It should have two colums, name and CertCount. Where name = planet name. and CertCount = total number of certificates all people with that homeworld have.
These are the tables i'm working with: http://pastebin.com/kNRNGQFv
This is my query so far:
SELECT bsg_people.homeworld, (SUM(cid)
AS 'CertCount'
FROM bsg_people
INNER JOIN bsg_cert_people ON id=cid)
GROUP BY bsg_people.homeworld;
I just can't seem to figure this out because there is no value to count the number of certificates each person has. I appreciate any help.
Use a simple count(*), without the subquery and join to the right column - your pastebin shows that the foreign key to person is on pid (not cid):
CONSTRAINT `bsg_cert_people_ibfk_2` FOREIGN KEY (`pid`) REFERENCES `bsg_people` (`id`)
Also, join to the planets tables to get the name of the planet in your output.
Try this:
select bsg_planets.name homeworld, count(*) CertCount
from bsg_planets
join bsg_people on bsg_planets.id = bsg_people.homeworld
join bsg_cert_people on id = pid
group by bsg_planets.name
Also, you had a syntax error: You quoted the alias "CertCount" like this: 'CertCount', but that's a string literal. You need an alias, without quotes, like this CertCount.
Rather than answer your question directly (which would sort of defeat the purpose of the homework which is for you to learn), I'll try to point you in the right direction :)
How are you joining bsg_cert_people onto bsg_people? Look at which fields are referring to people and which are referring to certifications, and make sure that you're using them the correct way. While not essential in this case, using table aliases (instead of just "id=cid") and neatening up the query a bit can really help with getting a better mental picture of what the joins and such are doing.
Today while writing one of the many queries that every developer in my company write every day I stumbled upon a question.
The DBMS we are using is Sql Server 2008
Say for example I write a query like this in the usual PERSON - DEPARTMENT db example
select * from person where id = '01'
And this query returns one row:
id name fk_department
01 Joe dp_01
The question is: is there a way (maybe using an addon) to make sql server write and execute a select like this
select * from department where id = 'dp_01'
only by for example clicking with the mouse on the cell containing the fk value (dp_01 in the example query)? Or by right click and selecting something like ("Go to pointed value")?
I hope I didn't wrote something stupid or impossible by definition
Not really, but that seems like a silly thing to do. Why would you want to confuse an id with a department name?
Instead, you could arrange things so you could do:
select p.*
from person p
where department = 'dp_01';
You would do this by adding a computed column department that references a scalar function that looks up the value in the department table. You can read about computed columns here.
However, a computed column would have bad performance characteristics. In particular, it would basically require a full table scan on the person table, even if that is not appropriate.
Another solution is to create a view, v_person that has the additional columns you want. Then you would do:
select p.*
from v_person p
where department = 'dp_01';
Why can't you write yourself by saying
select * from department where id =
(select fk_department from person where id = '01')