I have one small database for exercise, please see below ER-Diagram
I want to write a query that List student last and first names and majors for students who had at least one high grade (>= 3.5) in at least one course offered in fall of 2012.
My code below:
select s.StdNo,s.StdFirstName,s.StdLastName,s.StdMajor,e.EnrGrade,o.OfferNo,o.OffYear
from Enrollment e
join Offering o on e.OfferNo=o.OfferNo
join Student s on s.StdNo=e.StdNo
where e.EnrGrade >=3.5 and o.OffYear="2010";
But I got an SQL Error
[207] [S0001]: Invalid column name '2010'
I am confused about the error, value "2010" is NOT a column name, the Offyear is column. So why did this happen?
The basic query is not that hard, but I am stuck on (multiple)nested query.
Offyear is shown as a number, so you should compare against the number 2010, not the text "2010":
[...] and Offyear = 2010
Related
I'd like to answer a simple question: What is the avarage age of persons that own cars of specific colors ? ( Using Penatho BI, Yellowfin BI, MariaDB)
To do that the following model was designed.
One fact table "person_fact" containing the columns:
id, name and age.
And a dimension table "auto_dim" containing the columns:
id ( foreign key to person_fact table), car_type, color and hp.
As we see one person can own more than one car!
The problem is that in some filter scenarios, the persons that own several cars are counted multiple times, where they shouldn't.
For instance, trying to calcualte the avarage age of persons that own a "Black" or a "Red" car leads to a wrong result !!!
The SQL query that is generated by Pentaho BI is the following:
select
avg(`person_fact`.`age`) as `m0`
from `auto_dim` as `auto_dim`,
`person_fact` as `person_fact`
where `person_fact`.`id` = `auto_dim`.`id`
and `auto_dim`.`color` in ('Black', 'Red');
The same problem occurs using Yellowfin BI. The SQL query generated by Yellowfin BI:
SELECT DISTINCT AVG(`PERSON_FACT`.`age`)
FROM `person_fact` AS `PERSON_FACT`
INNER JOIN `auto_dim` AS `AUTO_DIM`
ON (`PERSON_FACT`.`id` = `AUTO_DIM`.`id`)
WHERE (`AUTO_DIM`.`color` IN ('Black', 'Red'))
The correct answer is 28.25 !
NOTE: Calculating the avg age with excel yields the right answer using a DAX expression!!
Question:
Is there any possibility to use something like DAX expression for Pentaho BI/Yellowfin BI to get right avg ?
Should i use a another model to fix the problem ?
Thanks in advance !!
I've only had a (frustrating) couple days experience with SQL Server, and I need some help, since I cant find anything related to my question when searching.
For background info, I'm working in an accountancy, and right now I'm trying to create a table for balance statements to use in crystal reports. Each invoice has multiple items, but for the statement I need to sum them all up with the invoice reference being the information that links the group of data that needs to be summarised.
So, what I need is to pull information from one table (dbo.SalesInvItems), this information including the date (InvDate), the due date (InvDueDate), and the customer name (CustomerName). This information stays the same with the Invoice Reference (InvRef), and it's what I want to use to link the two tables.
For example, Invoice Reference: 1478 will always have the date 14/05/18, the due date: 14/06/18 and the customer name: Pen Sellers Ltd.
The same Invoice Reference is used by multiple rows, but the only thing that changes (that I need) is the Invoice Item Total (InvItemTotal).
For example, the one reference will always be addressed to Pen Sellers, but one item has the Total as £13 and another item using the same reference is £20.
The Invoice Item Total is what I need to sum up. I want to add all the Invoice Item Total's together that have the same Invoice Reference, while joining the tables.
Sales Invoices
So when I've inserted the references into the table (sorry they're not the same in both pictures, I was having problems making examples and I made a mistake), I want to grab the information from the Invoice table to fill it in, going from this...
Pre Solution
To this...
Desired Result
The desired location is a table called dbo.Statement.
1.Is this even possible to do?
2.How would I go about doing this?
3.Is there a method I could use that would make sure that every time I insert an Invoice Reference into the Statement table, it would automatically pull out the data needed from the Invoice Table?
If any additional information is needed, just say and I'll do my best to provide it, I have never asked a question on here before and I'm new to SQL Server and coding in general.
Im using SQL Server Management Tool 2017
Thank You
Select item.InvRef
, item.CustomerName
, item.InvDate
, item.InvDueDate
, Sum(item.InvItemTotal) InvAmt
, sum(IsNull(payments.Amount,0)) PayAmount
, Sum(item.InvItemTotal) InvAmt - sum(IsNull(payments.Amount,0)) as Balance
from SalesInvItems item
left join payments -- you didn't define this
on item.InvRef = payments.InvRef
group by item.InvRef
, item.CustomerName
, item.InvDate
, item.InvDueDate
Select item.InvRef
, item.CustomerName
, item.InvDate
, item.InvDueDate
, Sum(item.InvItemTotal) InvAmt
from SalesInvItems item
left join Statement
on item.InvRef = Statement.Reference
group by item.InvRef
, item.CustomerName
, item.InvDate
, item.InvDueDate
I've got 2 tables and basically everything's the same except that in the 1st table we've got PLAYER_ID as the last column and in the 2nd table we've got NUM_OF_PLAYERS instead.
So here's what I've got:
BIRTHDAYS_TABLE:
int year, PLAYER_ID
1988, 12312321 which stands for 'Messi'
1988, 5541 which stands for 'Some other footballer'
1989, 12312322 which stands for 'CR7' etc
And then once in a while (once a year for this example) I want to 'cache' these results:
NUM_OF_PLAYERS_TABLE:
int year, int NUM_OF_PLAYERS
1988, 2
And the only query I support is "give me number of players who were born in X". Is there any solution in Cassandra so I don't have to write a bicycle and create some sort of scheduler (which runs once in a year for this example) and delete rows from the very 1st table and add this count() to the 2nd one?
Obviously my tables aren't that simple, but I believe that the idea is the same.
You can do it with count aggregation, like this:
select year, count(*) from first_table where year=1981;
then grab value returned as count, and insert into your 2nd table.
Actual implementation will depend on programming language that you're using.
Background
I have a database that hold records of all assets in an office. Each asset have a condition, a category name and an age.
A ConditionID can be;
In use
Spare
In Circulation
CategoryID are;
Phone
PC
Laptop
and Age is just a field called AquiredDate which holds records like;
2009-04-24 15:07:51.257
Example
I've created an example of the inputs of the query to explain better what I need if possible.
NB.
Inputs are in Orange in the above example.
I've split the example into two separate queries.
Count would be the output
Question
Is this type of query and result set possible using SQL alone? And if so where do I start? Would it be easier to use Ms Excel also?
Yes it is possible, for your orange fields you can just e.g.
where CategoryID ='Phone' and ConditionID in ('In use', 'In Circulation')
For the yellow one you could do a datediff of days of accuired date to now and divide it by 365 and floor that value, to get the last one (6+ years category) you need to take the minimum of 5 and the calculated value so you get 0 for all between 0-1 year old etc. until 5 which has everything above 6 years.
When you group by that calculated column and select the additional the count you get what you desire.
Task from exam for subject Database Systems:
I have following schema:
Excavator(EID, Type) - EID is a key
Company(Name, HQLocation) - Name is a key
Work(Name, EID, Site, Date) - All collumns together form a key
I have to write this query in relational algebra:
"Which company was digging on exactly one site on 1st of May?"
I don't know how to express it without aggregate functions (count). I know that people add these functions to relational algebra but we were forbidden to do it during this exam.
You can use standart set operations, division, projection, selection, join, cartesian product.
I forget the proper relational algebra syntax now but you can do
(Worked on >= 1 site on 1st May)
minus (Worked on > 1 site on 1st May)
--------------------------------------
equals (Worked on 1 site on 1st May)
A SQL solution using only the operators mentioned in the comments (and assuming rename) is below.
SELECT Name
FROM Work
WHERE Date = '1st May' /*Worked on at least one site on 1st May */
EXCEPT
SELECT W1.Name /*Worked more than one site on 1st May */
FROM Work W1
CROSS JOIN Work W2
WHERE W1.Name = W2.Name
AND W1.Date = '1st May'
AND W2.Date = '1st May'
AND W2.Site <> W2.Site
I assume this will be relatively straight forward to translate