Find the number of certifications held by people, grouped by planet. - sql

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.

Related

SQL refusing to do a join even when every identifier is valid? (ORA-00904)

Made this account just to ask about this question after being unable to find/expending the local resources I have, so I come to you all.
I'm trying to join two tables - ORDERS and CUSTOMER - as per a question on my assignment
For every order, list the order number and order date along with the customer number, last name, and first name of the customer who placed the order.
So I'm looking for the order number, date, customer number, and the full name of customers.
The code goes as such
SELECT ORDERS.ORDR_ORDER_NUMBER, ORDERS.ORDR_ORDER_DATE, ORDERS.ORDR_CUSTOMER_NUMBER, CUSTOMER.CUST_LAST, CUSTOMER.CUST_FIRST
FROM ORDERS, CUSTOMER
WHERE ORDERS.ORDR_CUSTOMER_NUMBER = CUSTOMER.CUST_CUSTOMER_NUMBER;
I've done this code without the table identifiers, putting quotation marks around ORDERS.ORDR_CUSTOMER_NUMBER, aliases for the two tables, and even putting a space after ORDR_ in both SELECT & WHERE for laughs and nothing's working. All of them keep coming up with the error in the title (ORA-00904), saying [ORDERS.]ORDR_CUSTOMER_NUMBER is the invalid identifier even though it shouldn't be.
Here also are the tables I'm working with, in case that context is needed for help.
Anyway, the query that produces the result you want should take the form:
select
o.ordr_order_number,
o.ordr_order_date,
c.cust_customer_number,
c.cust_last,
c.cust_first
from orders o
join customer c on c.cust_customer_number = o.ordr_customer_number
As you see the query becomes a lot easier to read and write if you use modern join syntax, and if you use table aliases (o and c).
You have to add JOIN or INNER JOIN to your query. Because the data comes from two different tables the WHERE clause will not select both.
FROM Orders INNER JOIN Customers ON Orders.order_Customer_Number = Customer.Cust_Customer_Number

Coding Inner Join subquery as field in query

After looking at example after example of both inner joins and subqueries as fields, I'm apparently not getting some aspect, and I would appreciate help please. I am trying to write one query that must, alas, run in MS Access 2007 to talk to an Oracle database. I have to get values from several different places for various bits of data. One of those bits of data is GROUP_CODE (e.g., faculty, staff, student, alum, etc.). Getting that is non-trivial. I am trying to use two inner joins to get the specific value. The value of borrower category must be the value for my main row in the outer query. Here is what this looks like:
Patron table Patron_Barcode table Patron_Group table
Patron_id Barcode Patron_Group_iD
Barcode Patron_Group_id PATRON_Group_Code
I want to get the PATRON_GROUP.PATRON_GROUP_CODE. This is only one of 35 fields I need to get in my query. (Yes, that's terrible, but wearing my librarian hat, i can't write the Java program I'd like to write to do this in a snap.)
So as a test, I wrote this query:
select PATRON.PATRON_ID As thePatron,
(SELECT PATRON_GROUP.PATRON_GROUP_CODE As borrowwerCategory
FROM (PATRON_GROUP
INNER JOIN PATRON_BARCODE ON PATRON_GROUP.PATRON_GROUP_ID = PATRON_BARCODE.PATRON_GROUP_ID
) INNER JOIN PATRON ON PATRON_BARCODE.PATRON_ID = thePatron.PATRON_ID
));
I don't know what I'm doing wrong, but this doesn't work. I've written a fair amount of SQL in my time, but never anything quite like this. What am I doing wrong?
PATRON.BARCODE is the foreign key for the BARCODE table.
PATRON_BARCODE.PATRON_GROUP_ID is the foreign key for the PATRON_GROUP table. PATRON_GROUP_CODE in PATRON_GROUP is he column value that I need.
PATRON.BARCODE -> BARCODE.PATRON_GROUP_ID -> PATRON_GROUP.PATRON_GROUP_CODR>
The main table, PATRON, will have lots of other things, like inner and outer join to PATRON_ADDRESS, etc., and I can't just do an inner join directly to what I want in my main query. This has to happen in a subquery as a field. Thanks.
Ken

SQL join with references to references

I am still new to SQL. I have been making good progress on my project until I ran into this problem. I have tried to search the net for this kind of problem but I cannot find anything specific to this or I am not using the correct keywords in my search.
I have three tables relevant to this problem. Apparently I do not have any kind of "describe table" command to be able to copy the output. My other queries with joins are working as expected.
Table 1 - "Sites"
ID int auto-increment key, site_code short text, site_name short text, more but not relevant.
Table 2 - "Hubs"
ID int auto-increment key, HUB int (lookup from Sites.ID), more but not relevant.
Table 3 - "DialPlan"
ID int auto-increment key, site int (lookup from Sites.ID), HUB int (lookup from Hubs.HUB), more but not relevant.
When viewing the query for "DialPlan" I need to see "DialPlan.site" being replaced by "Sites.site_code" for that specific int. I need to see "DialPlan.HUB" being replaced by "Sites.site_code" for that specific int. Example of table output without joins:
DialPlan: 28, 29, 2, 203 That last number is not relevant.
Sites.ID = 29, Sites.site_name = BENN. Hubs.ID = 2, Hubs.HUB = 27, Sites.ID = 27, Sites.site_name = BRAG. So, the output I need to see when using the join is: 28, BENN, BRAG, 203. I am not getting that, I am getting: 28, BENN, BENN, 203.
My search query is:
select
Sites.site_code, Sites.site_name, Sites.site_code as Hubs.HUB,
DialPlan.OC
from
DialPlan
left join
Sites on DialPlan.site = Sites.ID
left join
Hubs on DialPlan.HUB = Hubs.ID
left join
Hubs on Hubs.HUB = Sites.ID;
I have tried to change field 3 using "AS" and even tried "=" and several other things. If I try to put field 3 as "Sites.site_code" then the output is the same as the first "Sites.site_code" lookup. I am not sure how to proceed. I have tried so many things now that I am not even sure exactly what I have tried. I saw one thread where there were multiple dots per column and I have no idea what that is used for. Does anyone have any ideas?
OK, I have found the answer and it is called an inner query. Actually there are two inner queries. I am posting this so that others may benefit from this. The problem with referencing the first table from two fields that are on the same table is that SQL cannot determine that the second call means a new search. So, you must perform an inner query to resolve this. Here is the code. As an Access admin I have always been able to get this kind result easy but I am behind the power curve for SQL. Here is the working code sample.
SELECT Sites.site_code, Sites.site_name,
( SELECT site_code FROM Sites WHERE ID =
( SELECT HUB FROM Hubs WHERE DialPlan.HUB = Hubs.ID )
),
DialPlan.OC
FROM DialPlan
LEFT JOIN Sites
ON DialPlan.site = Sites.ID;
The output is what I was looking for, "BENN Benning BRAG 203". I hope this helps someone.
When you use the AS clause you are just giving that column a title for your table. It will not fill in the data from your alias in place of the data you are aliasing.
If you want to list the data for Hubs.hub you should SELECT Hubs.hub and then give it the title you want using AS mytitle.
Also you dint need that last join as your tables are already joined.
Also, the describe command is DESC and it should work... DESC sites
select
Sites.site_code, Sites.site_name, Hubs.HUB as Site, DialPlan.OC
from
DialPlan
left join
Sites on DialPlan.site = Sites.ID
left join
Hubs on DialPlan.HUB = Hubs.ID

How do you JOIN tables to a view using a Vertica DB?

Good morning/afternoon! I was hoping someone could help me out with something that probably should be very simple.
Admittedly, I’m not the strongest SQL query designer. That said, I’ve spent a couple hours beating my head against my keyboard trying to get a seemingly simple three way join working.
NOTE: I'm querying a Vertica DB.
Here is my query:
SELECT A.CaseOriginalProductNumber, A.CaseCreatedDate, A.CaseNumber, B.BU2_Key as BusinessUnit, C.product_number_desc as ModelNumber
FROM pps_sfdc.v_Case A
INNER JOIN reference_data.DIM_PRODUCT_LINE_HIERARCHY B
ON B.PL_Key = A.CaseOriginalProductLine
INNER JOIN reference_data.DIM_PRODUCT C
ON C.product_line_code = A.CaseOriginalProductLine
WHERE B.BU2_Key = 'XWT'
LIMIT 20
I have a view (v_Case) that I’m trying to join to two other tables so I can lookup a value from each of them. The above query returns identical data on everything EXCEPT the last column (see below). It's like it's iterating through the last column to pull out the unique entries, sort of like a "GROUP BY" clause. What SHOULD be happening is that I get unique rows with specific "BusinessUnit" and "ModelNumber" for that record.
DUMEPRINT 5/2/2014 8:56:27 AM 3002845327 JJT Product 1
DUMEPRINT 5/2/2014 8:56:27 AM 3002845327 JJT Product 2
DUMEPRINT 5/2/2014 8:56:27 AM 3002845327 JJT Product 3
DUMEPRINT 5/2/2014 8:56:27 AM 3002845327 JJT Product 4
I modeled my solution after this post:
How to deal with multiple lookup tables for beginners of SQL?
What am I doing wrong?
Thank you for any help you can provide.
Data issue. General rule in trouble shooting these is the column that is distinct (in this case C.product_number_desc as ModelNumber) for each record is generally where the issue is going to be...and why I pointed you towards dim_product.
If you receive duplicates, this query below will help identify if this table is giving you the issues. Remember key in this statement can be multiple fields...whatever you are joining the table on:
Select key,count(1) from table group by key having count(1)>1
Other options for the future...don't assume it's your code, duplicates like this almost always point towards dirty data (other option is you are causing cross joins because keys are not correct). If you comment out the 'c' table and the column referred to in the select clause, you would have received one row...hence your dupes were coming from the 'c' table here.
Good luck with it

How to design the database schema to link two tables via lots of other tables

Although I'm using Rails, this question is more about database design. I have several entities in my database, with the schema a bit like this: http://fishwebby.posterous.com/40423840
If I want to get a list of people and order it by surname, that's no problem. However, if I want to get a list of people, ordered by surname, enrolled in a particular group, I have to use an SQL statement that includes several joins across four tables, something like this:
SELECT group_enrolment.*, person.*
FROM person INNER JOIN member ON person.id = member.person_id
INNER JOIN enrolment ON member.id = enrolment.member_id
INNER JOIN group_enrolment ON enrolment.id = group_enrolment.enrolment_id
WHERE group_enrolment.id = 123
ORDER BY person.surname;
Although this works, it strikes me as a bit inefficient, and potentially as my schema grows, these queries could get more and more complicated.
Another option could be to join the person table to all the other tables in the query by including person_id in the other tables, then it would just be one single join, for example
SELECT group_enrolment.*, person.*
FROM person INNER JOIN group_enrolment ON group_enrolment.person_id
WHERE group_enrolment.id = 123
ORDER BY person.surname;
But this would mean that in my schema, the person table is joined to a lot of other tables. Aside from a complicated schema diagram, does anyone see any disadvantages to this?
I'd be very grateful for any comments on this - whether what I'm doing now (the many table join) or the second solution or another one that hasn't occurred to me is the best way to go.
Many thanks in advance
Well, joins are what databases do. Having said that, you may consider propagating natural keys in your model, which would then allow you to skip over some tables in joins. Take a look at this example.
EDIT
I'm not saying that this will match your model (problem), but just for fun try similar queries on something like this: