Create new table from average of multiple columns in multiple tables - sql

I have the following query:
CREATE TABLE Professor_Average
SELECT Instructor, SUM( + instreffective_avg + howmuchlearned_avg + instrrespect_avg)/5
FROM instreffective_average, howmuchlearned_average, instrrespect_average
GROUP BY Instructor;
It is telling me that Instructor is ambiguous. How do I fix this?

Qualify instructor with the name of the table it came from.
For example: instreffective_average.Instructor
If you don't do this, SQL will guess which table of the query it came from, but if there are 2 or more possibilities it doesn't try to guess and tells you it needs help deciding.

Your query most likely fails in more than one way.
In addition to what #Patashu told you about table-qualifying column names, you need to JOIN your tables properly. Since Instructor is ambiguous in your query I am guessing (for lack of information) it could look like this:
SELECT ie.Instructor
,SUM(ie.instreffective_avg + h.howmuchlearned_avg + ir.instrrespect_avg)/5
FROM instreffective_average ie
JOIN howmuchlearned_average h USING (Instructor)
JOIN instrrespect_average ir USING (Instructor)
GROUP BY Instructor
I added table aliases to make it easier to read.
This assumes that the three tables each have a column Instructor by which they can be joined. Without JOIN conditions you get a CROSS JOIN, meaning that every row of every table will be combined with every row of every other table. Very expensive nonsense in most cases.
USING (Instructor) is short syntax for ON ie.Instructor = h.Instructor. It also collapses the joined (necessarily identical) columns into one. Therefore, you would get away without table-qualifying Instructor in the SELECT list in my example. Not every RDBMS supports this standard-SQL feature, but you failed to provide more information.

Related

Having troubles with a conditional count in SQL

I'm working on an SQL project (involving a library database) and I'm having a hard time figuring out how to make a conditional count.
So, I have 4 tables: Imprumuturi, Cititori, Autori, Carti. I need to list the 'Cititori' that have more than one borrowed 'Carti' at the current time.
I tried to use
SELECT cititori.nume_cititor,COUNT(imprumuturi.pk_cititor)
AS numar_imprumuturi FROM cititori, imprumuturi
WHERE imprumuturi.data_return IS NULL GROUP BY cititori.nume_cititor
HAVING COUNT(imprumuturi.pk_cititor)>1
ORDER BY cititori.nume_cititor;
And while it lists all the 'Cititori", it doesn't count the number of active borrowed 'Carti' as it should.
Can I get a hint or some help on how to make it work?
These are the fields of my database
Seems you missed the relation between the tables:
SELECT cititori.nume_cititor,COUNT(imprumuturi.pk_cititor)
AS numar_imprumuturi
FROM cititori
INNER JOIN imprumuturi ON imprumuturi.pk_cititori = cititori.pk_cititori
WHERE imprumuturi.data_return IS NULL
GROUP BY cititori.nume_cititor
HAVING COUNT(imprumuturi.pk_cititor)>1
ORDER BY cititori.nume_cititor;
As suggested, you should not use the old implicit join syntax based on comma-separated table names and where condition, but use explicit join syntax.

Error when using join and join produces error

I am trying to make groups and make joins with the below tables but I get an
ORA-00918: column ambiguously defined
error.
Any ideas how to fix?
SELECT staffn, job, COUNT(*)"staffcount", AVG(sal)"AverageSal"
FROM staff, shop
WHERE staff.shopno= shop.shopno
GROUP BY shopno, job;
You should use proper alias and your group by clause must include all the unaggregated columns as follows:
SELECT s.staffn, sh.job,
COUNT(*)"staffcount",
AVG(s.sal)"AverageSal"
FROM staff s join shop sh
WHERE s.shopno= sh.shopn
Group by s.staffn, sh.job
Did you mean to include staffn In your select? I would guess that this was unique to a row in staff and would make selecting the average (or any other aggregation) sal a bit useless (and if you did want to do that, you’d need to include it in the group by). I think you really meant to select the same column in your group by.
Your error is telling you that Oracle doesn’t know where a column should be taken from, multiple row sources in your query could provide it. The complete error message will also make it clear which column this is referring to, but we can already see that at least shopno is shared, we can arbitrarily take it from staff.
SELECT staff.shopno, job, COUNT(*)"staffcount", AVG(sal)"AverageSal"
FROM staff, shop
WHERE staff.shopno= shop.shopno
GROUP BY staff.shopno, job;
In both tables you used, there is at least a field with the same name. You must specify which field used which table.
for more information
Never use commas in the FROM clause. Always use proper, explicit, standard, readable JOIN syntax.
In a query that references multiple tables, qualify all column references.
You haven't shown the layout of your tables, but you presumably want something like this:
SELECT st.staffn, st.job, COUNT(*) as staffcount,
AVG(st.sal) as AverageSal
FROM staff st JOIN
shop sh
ON st.shopno = sh.shopno
GROUP BY st.staffn, st.job;
This assumes that all the columns come from the staff table, which seems reasonable enough in the absence of other information.

SQL Oracle: Query of showing two columns from two tables as one and counting into numeric value

The query is:
I have a member table and a stage table, the 'band_name' is the foreign key in the members table.
I need to show the stage name (stage_name) and how many members will be performing on each stage.
I have attempted so far the following:
SELECT stage_name, member_ID,member.band_name
FROM stage, member
WHERE stage.stage_name = member.band_name
ORDER BY stage_name, member.band_name, member_ID;
This shows one stage_name and the three members but NOT as a number e.g.3 and none of the other stage_names
I think I may need to use COUNT and maybe also INNER join?
FYI - I am very new to SQL oracle
All help appreciated.
You need to learn proper, explicit, standard, readable JOIN syntax. Commas are history. JOIN is not only the future, but the present and much of the past as well.
Then, you want LEFT JOIN and GROUP BY:
SELECT stage_name, COUNT(m.member_ID)
FROM stage s LEFT JOIN
member m
ON s.stage_name = m.band_name
GROUP BY s.stage_name
ORDER BY s.stage_name;

the specified field 'Match ID' could refer to more than one table listed in the FROM clause of your sql statement

I am trying to give the number of matches that a player did not play but listed in the team. If he hasnt played his Minutes per game will be zero which i have implemented. PLease PLease Help!!!
SELECT tblGameResults.MatchID, Player_ID_Number, Minutes_Per_Game
FROM
tblGameResults
INNER JOIN
tblPlayerStatistics ON tblGameResults.MatchID = tblPlayerStatistics.MatchID
WHERE Minutes_Per_Game = 0
GROUP BY
tblGameResults.MatchID
Although your query looks conceptually like it would work, here are a few pointers (I am making some guesses on the tables where Minutes_Per_Game and Player_ID_Number come from):
Give aliases to all of your table names
SELECT game.MatchID, stats.Player_ID_Number, stats.Minutes_Per_Game
FROM
tblGameResults as game
INNER JOIN
tblPlayerStatistics as stats ON game.MatchID = stats.MatchID
WHERE stats.Minutes_Per_Game = 0
GROUP BY
game.MatchID
This should help you identify where your problems are, or it will help the database know where to pull columns from. Additionally, you are selecting three columns. You should probably group by all of them unless you want to do some aggregate functions on the last two in your select statement.

Why is selecting specified columns, and all, wrong in Oracle SQL?

Say I have a select statement that goes..
select * from animals
That gives a a query result of all the columns in the table.
Now, if the 42nd column of the table animals is is_parent, and I want to return that in my results, just after gender, so I can see it more easily. But I also want all the other columns.
select is_parent, * from animals
This returns ORA-00936: missing expression.
The same statement will work fine in Sybase, and I know that you need to add a table alias to the animals table to get it to work ( select is_parent, a.* from animals ani), but why must Oracle need a table alias to be able to work out the select?
Actually, it's easy to solve the original problem. You just have to qualify the *.
select is_parent, animals.* from animals;
should work just fine. Aliases for the table names also work.
There is no merit in doing this in production code. We should explicitly name the columns we want rather than using the SELECT * construct.
As for ad hoc querying, get yourself an IDE - SQL Developer, TOAD, PL/SQL Developer, etc - which allows us to manipulate queries and result sets without needing extensions to SQL.
Good question, I've often wondered this myself but have then accepted it as one of those things...
Similar problem is this:
sql>select geometrie.SDO_GTYPE from ngg_basiscomponent
ORA-00904: "GEOMETRIE"."SDO_GTYPE": invalid identifier
where geometrie is a column of type mdsys.sdo_geometry.
Add an alias and the thing works.
sql>select a.geometrie.SDO_GTYPE from ngg_basiscomponent a;
Lots of good answers so far on why select * shouldn't be used and they're all perfectly correct. However, don't think any of them answer the original question on why the particular syntax fails.
Sadly, I think the reason is... "because it doesn't".
I don't think it's anything to do with single-table vs. multi-table queries:
This works fine:
select *
from
person p inner join user u on u.person_id = p.person_id
But this fails:
select p.person_id, *
from
person p inner join user u on u.person_id = p.person_id
While this works:
select p.person_id, p.*, u.*
from
person p inner join user u on u.person_id = p.person_id
It might be some historical compatibility thing with 20-year old legacy code.
Another for the "buy why!!!" bucket, along with why can't you group by an alias?
The use case for the alias.* format is as follows
select parent.*, child.col
from parent join child on parent.parent_id = child.parent_id
That is, selecting all the columns from one table in a join, plus (optionally) one or more columns from other tables.
The fact that you can use it to select the same column twice is just a side-effect. There is no real point to selecting the same column twice and I don't think laziness is a real justification.
Select * in the real world is only dangerous when referring to columns by index number after retrieval rather than by name, the bigger problem is inefficiency when not all columns are required in the resultset (network traffic, cpu and memory load).
Of course if you're adding columns from other tables (as is the case in this example it can be dangerous as these tables may over time have columns with matching names, select *, x in that case would fail if a column x is added to the table that previously didn't have it.
why must Oracle need a table alias to be able to work out the select
Teradata is requiring the same. As both are quite old (maybe better call it mature :-) DBMSes this might be historical reasons.
My usual explanation is: an unqualified * means everything/all columns and the parser/optimizer is simply confused because you request more than everything.