Trying to solve some queries from sql zoo to practice sql skills
I have a table nobel with columns (year, subject, winner) which have information on the people who have earned noble prizes in a given year for a given subject.
So I assume the primary key to be composite of (year, subject, winner).
The problem I am trying to solve is: Show winners who have won more than one subject.
The output of the SQL query should have just one column with the winner names.
I feel that I should be using group by and using having(count(winner)) >1. But I think I need to group by by subject and that's where my problem is.
I am not looking for a query. If you can provide me with more logic than query that would help. Also do not worry about the database it needs to be implemented on. I am just practicing these questions.
This should give you people who won on multiple different subjects in any number of years:
SELECT winner
FROM nobel
GROUP BY winner
HAVING COUNT(DISTINCT subject) > 1
For a specific year, just add WHERE year = <whatever> (or GROUP BY year for all years), though no person in history won a Nobel for two subjects in a single year - but who knows what future brings ;)
You should really consider creating a SQLite or MySQL database on your local machine so that you can practice making queries.
The primary key is irrelevant to your question, don't worry about it.
You are thinking along the correct lines - you will need a group by and having clause. If you group by winner, then your proposed query should work. I've added a count of wins.
select
winner, count(winner) as wins
from
nobel
group by winner
having (count(winner)) > 1
SELECT winner
FROM nobel
GROUP BY winner
HAVING COUNT(winner) > 1
This is the simplest way to do it ......
Related
Let me illustrate this:
Student_ID
Course
StudentID1
CourseA
StudentID2
CourseB
StudentID3
CourseA CourseB
There is an existing table that has data that looks like the one above (Not exactly Student & Course, this is more for illustration purpose) and my job is to do a count of how many students for each course. The table is very huge and I do not know how many and what are the courses are out there (Easily in thousands), so wonder if there is a way I can get a list of all these courses and their counts through SQL?
The current method that my team did is SELECT DISTINCT COURSE, COUNT(STUDENT_ID) FROM TABLE GROUP BY COURSE, but this does not work because it treats "CourseA CourseB" as its own.
There are some other columns in this table that I might need to do a SUM as well.
Appreciate any advice on this, thanks!
you could use below to find number of students for each course:
select course, count(*) as no_of_students
from table
group by course;
From the following table, write a SQL query to find the Nobel Prize winners for the subject not started with the letter 'P'. Return year, subject, winner, country, and category. Order the result by year, descending.
Sample table : nobel_win
Solution:
SELECT *
FROM nobel_win
WHERE subject NOT LIKE 'P%'
ORDER BY year DESC, winner;
I don't understand why the solution put winner at the end. It seems that winner is not required.
Most likely, the winner column was tagged to the end of the ORDER BY clause to break the tie should 2 or more records happen to have the same year. If that be the case, then simply ordering by year descending might leave all records belonging to a given year appearing unsorted. The query you posted above resolves this by ordering all record within a given year by the winner name.
I use oracle 11g , so i read alot of artics about it but i dont understand
how exactly its happened in database , so lets say that have two tables:
select * from Employee
select * from student
so when we want to make group by in multi columns :
SELECT SUBJECT, YEAR, Count(*)
FROM Student
GROUP BY SUBJECT, YEAR;
so my question is: what exactly happened in database ? i mean the query count(*) do first in every column in group by and then sort it ? or what? can any one explain it in details ?.
SQL is a descriptive language, not a procedural language.
What the query does is determine all rows in the original data where the group by keys are the same. It then reduces them to one row.
For example, in your data, these all have the same data:
subject year name
English 1 Harsh
English 1 Pratik
English 1 Ramesh
You are saying to group by subject, year, so these become:
Subject Year Count(*)
English 1 3
Often, this aggregation is implemented using sorting. However, that is up to the database -- and there are many other algorithms. You cannot assume that the database will sort the data. But, if it easier for you to think of it, you can think of the data being sorted by the group by keys, in order to identify the groups. Just one caution, the returned values are not necessarily in any particular order (unless your query includes an order by).
I have two tables in my DB:
Building(bno,address,bname) - PK is bno. bno
Room(bno,rno,floor,maxstud) - PK is bno,rno (together)
The Building table stands for a building number, address and name.
The Room table stands for building number, room number, floor number and maximum amount of students who can live in the room.
The query I have to write:
Find a building who has at least 10 rooms, which the maximum amount of students who can live in is 1. The columns should be bno, bname, number of such rooms.
What I wrote:
select building.bno, building.bname, count(rno)
from room natural join building
where maxstud =1
group by bno, bname
having count(rno)>=10
What the solution I have states:
with temp as (
select bno, count(distinct rno) as sumrooms
from room
where maxstud=1
group by bno
)
select bno, bname, sumrooms
from building natural join temp
where sumrooms>=10
Is my solution correct? I didn't see a reason to use a sub-query, but now I'm afraid I was wrong.
Thanks,
Alan
Your query will perform faster but I'm afraid won't compile because you are not including every unaggregated column in the GROUP BY clause (here: building.bname).
Also, the solution that you have which isn't yours counts distinct room numbers, so one may conclude that a building can have several rooms with the same numbers for example on different floors, so that a room would be identified correctly by the unique triple (bno, rno, floor).
Given what I've wrote above your query would look:
select building.bno, building.bname, count(distinct rno)
from room natural join building
where maxstud = 1
group by 1,2 -- I used positions here, you can use names if you wish
having count(distinct rno) >= 10
Your solution is better.
If you are unsure, run both queries on a sample dataset and convince yourself that the results are the same.
So I'm taking a course on learning basic SQL (using Oracle), and I felt like I had become fairly fluent with using SELECT statements (grouping, joining, having, etc), but now I'm at a loss on how to deal with this latest problem.
I need to write a statement that would only display rows with more than one piece of data. So, say I had
COMPANY PRODUCT
One Car
One Book
Two Game
it should only list company 'One'. But I can't find anything online to help me.
Select Company
From YourTableName
Group By Company
Having Count(*) > 1
better way to know count of each company is :
Select Company,Count(*)
From Table
Group By Company
Having Count(*) > 1