This question already exists:
SQL Query geting infromation from table
Closed 9 years ago.
I would like to do two things but I've goten stuck.
First of all I would like to write a SQL statement to show me all the sport and all competition days each sport has. The table Event looks like this
Competitor ID sports branch distance men's/women
1 Running Long-Distance 50000 MEN
I also have an Table named EventDay which has CompetitorID, date ,arena and spectators.
CompetitorID Date Arena Spectators
1 08/11/11 Olympus 500
There is obviously going to be an join statment here but I cant get it to work.
In the next table below I would like to get out exactly how mand gold medals the invidual countries have goten from the branch Athletics. I would also like it to be devided in the sex and sorted after the name of the country.
Land Sex Ammount gold
USA L 2
USA M 4
Ryss L 3
Ryss H 2
TRY THIS
SELECT Country,Sex
, sum(AmountGold) as TotalGold
FROM YourTable
GROUP BY
Country,Sex
ORDER BY
Country,Sex
I think this is what you need
select Country
, Sex
, sum(case when MedalType = 'Gold' then 1 else 0 end) as AmountGold
from YourTable
group by
Country
, Sex
order by
AmountGold desc
Try this:
SELECT COUNTRY,
SUM(AMOUNT_GOLD) AS TOTAL_GOLD
FROM ATHLETICS
GROUP BY LAND,
SEX
ORDER BY LAND
Related
I am not entirely sure even how to name this post, because I do not know exactly how to ask it.
I have three tables. One with users, one with foods and one with the users rating of the foods, like such (simplified example):
Foods
id name type
---------------------
1 Apple fruit
2 Banana fruit
3 Steak meat
Users
id username
-----------------
1 Mark
2 Harrison
3 Carrie
Scores (fid = food id, uid = user id)
fid uid score
---------------------
1 1 3
1 2 5
2 1 2
3 2 3
Now, I have this query, which works perfectly:
SELECT fn.name as Food, ROUND(AVG(s.score),1) AS AvgScore FROM Foods fn LEFT JOIN Scores s ON fn.id = s.fid GROUP BY fn.id ORDER BY fn.name ASC
As you can tell, it lists all names from Foods including an average from all users ratings of the food.
I also want to add the unique users own score. (Assume that when Mark is logged in, his uid is set in a session variable or whatever)
I need the following output, if you are logged in as Mark:
Food AvgScore Your Score
Apple 4 3
I have made several attempts to make this happen, but I cannot find the solution. I have learned that if you have a question, it is very likely that someone else has asked it before you do, but I do not quite know how to phrase the question, so I get no answers when googling. A pointer in the right direction would be much appreciated.
You can try with case:
SELECT fn.name as Food,
ROUND(AVG(s.score),1) AS AvgScore,
sum(case s.uid = $uid when s.score else 0 end) as YourScore
FROM Foods fn
LEFT JOIN Scores s ON fn.id = s.fid
GROUP BY fn.id
ORDER BY fn.name ASC
$uid is variable off course.
I have the following data stored in my database.
I want to know what the 10 most searched parts are for every car.
Below I made an example of the data that is stored in the database.
One table contains the names of the cars with the car id.One table contains the requests with one or more request id('s) for every car.One table contains the request id with the name of the requested part.
Table cars
audi (7)
bmw (12)
Table request
7 (100)
7 (234)
7 (367)
7 (562)
7 (729)
7 (765)
7 (881)
Table request_parts
100 (achterband)
234 (voorband)
367 (motor)
562 (accu)
729 (achterband)
765 (kopeling)
881 (koeling)
What the query should return is something like this, as in the example 'achterband' was found twice
audi achterband 2
audi voorband 1
audi motor 1
audi accu 1
audi kopeling 1
The query that I currently have counts how often the part 'motor' has been requested for every car. however I can't find out how to do this not just for one product but for all of them at the same time. right now its not important to have the name of the car as the id is already shown.
SELECT COUNT(*), requests.sibben_brand_id, request_parts.name
FROM request_parts
JOIN requests ON requests.id = request_parts.request_id
WHERE requests.sibben_brand_id IS NOT NULL
AND request_parts.name LIKE 'motor'
GROUP BY requests.sibben_brand_id
ORDER BY COUNT(*) DESC `
Does any one has a idea how i could get the correct data?
try with this:
SELECT COUNT(*), requests.sibben_brand_id, request_parts.name
FROM request_parts
JOIN requests ON requests.id = request_parts.request_id
WHERE requests.sibben_brand_id IS NOT NULL
GROUP BY requests.sibben_brand_id,request_parts.name
ORDER BY COUNT(*) DESC `
with
cars table as (id,name)
request table as (id,car_id,request_id)
request_parts table as (id,request_id,part_name)`
the following query returns top 10 records
select top 10 c.name, rqp.part_name,count(*) as repetition
from request as r, request_parts as rqp, cars as c
where rqp.request_id = r.request_id AND r.car_id = c.Id
group by rqp.part_name,c.name
order by repetition desc`
I have a table with ID numbers of people and then items of food they've ordered:
table "food_id"
food id
ham 1
cheese 2
turkey 2
ham 3
ham 4
bread 5
cheese 6
turkey 6
cheese 7
And I'd like to use SQL to figure out, for each id, the total number of other IDs who ordered at least one of the same food items. For the above example, the answer should be:
"result_table"
count id
3 1
3 2
3 3
3 4
1 5
3 6
3 7
The challenge is to avoid double counting here. For example, person number 2 got both cheese and turkey, so we want his final count to be 3 because person # 2, 6, and 7 got cheese, and person # 2 and 6 got turkey, and there are 3 unique IDs in this list of (2,6,7,2,6).
My initial thoughts were to first get a table with food items to distinct ID numbers, and then to join this table with the original table and then group by ID number and get a count of the distinct number of IDs. However, I'm a beginner to SQL and can't figure out how to implement the code correctly.
Any direction would be greatly appreciated.
To avoid the problem with the double counting you can concat both ids from the join and count only distinct combinations. I add a separator to make the combination unique with greater id values:
SELECT
COUNT(DISTINCT CONCAT(f1.id, ',', f2.id)) as count,
f1.id
FROM
food_id f1
INNER JOIN
food_id f2
ON
f1.food = f2.food
GROUP BY f1.id;
See demo
Like you said, you can do a self join. You can join by food, and count the number of distinct matching ids.
select
a.id, -- Person you're investigating
count(distinct b.id) as samefoodcount -- number of people sharing the same food
from
food_id a
inner join food_id b on b.food = a.food
group by
a.id
Here you can see the query in action: http://sqlfiddle.com/#!2/c53884/1
You can run the following query to get the desired output:
select MAX(T.total),id
from table_name, (select count(*) as total,food from table_name group by food) T
where table_name.food=T.food
group by id
Check the DEMO
The problem I am having is in relation to comparing two tables, and returning results which do not feature in both tables. I am using a theatre based situtation with bookings and seat numbers.
So my first table is the seat table looking like this.
row_no area_name
a01 front stalls
a02 front stalls
there are several area names that can be used, but they all use the same format as the above. For this example I will use seats a01 through a20 only in the front stalls.
The second table is the booking table looking like this
ticket_no row_no date_time customer_name
001070714 a01 21:00 7.7.14 John Doe
002070714 a02 21:00 7.7.14 John Doe
What I am trying to achieve is to compare the list of booked seats at that specific showtime to the total list of seats from the seat table, then group the results by area_name so I hopefully acheive results like
area_name row_no
front stalls 18
where 18 would be the number of free seats from the complete set of 20 described in the seat table.
How would I set about achieving this answer?
EDIT
This is what I've tried so far
SELECT
DISTINCT s.area_name, row_no
FROM seat AS s
FROM booking AS b
COUNT * WHERE s.row_no != b.row_no
WHERE b.title = rammstein
WHERE s.area_name = 'front stalls'
GROUP BY s.area_name;
Try something like:
SELECT seat_q.area_name, (seat_q.num_seats - COUNT(*) AS occupied_seats) AS free_seats
FROM booking b
WHERE row_no IN (
SELECT s.row_no
FROM seat s
WHERE s.area_name = 'front stalls'
GROUP BY s.area_name)
JOIN
(SELECT s.row_no, s.area_name, COUNT(s.*) AS num_seats
FROM seat s
WHERE s.area_name = 'front stalls'
GROUP BY s.area_name) AS seat_q
ON seat_q.row_no = b.row_no
WHERE b.date_time = '21:00, 7.7.14'
I am writing a query against an advanced many-to-many table in my database. I call it an advanced table because it is a many-to-many table with and extra field. The table maps data between the fields table and the students table. The fields table holds potential fields that a student can used, kind of like a contact system (i.e. name, school, address, etc). The studentvalues table that I need to query against holds the field id, student id, and the field answer (i.e. studentid=1; fieldid=2; response=Dave Long).
So my table looks like this:
What I need to do is take a few passed in values and create a grouped accumulated report. I would like to do as much in the SQL as possible.
So that data that I have will be the group by field (a field id), the cumulative field (a field id) and I need to group the students by the group by field and then in each group count the amount of students in the cumulative fields.
So for example I have this data
ID STUDENTID FIELDID RESPONSE
1 1 2 *(city)* Wallingford
2 1 3 *(state)* CT
3 2 2 *(city)* Wallingford
4 2 3 *(state)* CT
5 3 2 *(city)* Berlin
6 3 3 *(state)* CT
7 4 2 *(city)* Costa Mesa
8 4 3 *(state)* CA
I am hoping to write one query that I can generate a report that looks like this:
CA - 1 Student
Costa Mesa 1
CT - 3 Students
Berlin 1
Wallingford 2
Is this possible to do with a single SQL statement or do I have to get all the groups and then loop over them?
EDIT Here is the code that I have gotten so far, but it doesn't give the proper stateSubtotal (the stateSubtotal is the same as the citySubtotal)
SELECT state, count(state) AS stateSubtotal, city, count(city) AS citySubtotal
FROM(
SELECT s1.response AS city, s2.response AS state
FROM studentvalues s1
INNER JOIN studentvalues s2
ON s1.studentid = s2.studentid
WHERE s1.fieldid = 5
AND s2.fieldid = 6
) t
GROUP BY city, state
So to make a table that looks like that, I would assume something like
State StateSubtotal City CitySubtotal
CA 1 Costa Mesa 1
CT 3 Berlin 1
CT 3 Wallingford 2
Would be what you want. We can't just group on Response, since if you had a student answer LA for city, and another student that responds LA for state (Louisiana) they would add. Also, if the same city is in different states, we need to first lay out the association between a city and a state by joining on the student id.
edit - indeed, flawed first approach. The different aggregates need different groupings, so really, one select per aggregation is required. This gives the right result but it's ugly and I bet it could be improved on. If you were on SQL Server I would think a CTE would help but that's not an option.
select t2.stateAbb, stateSubtotal, t2.city, t2.citySubtotal from
(
select city, count(city) as citySubTotal, stateAbb from (
select s1.Response as city, s2.Response as StateAbb
from aaa s1 inner join aaa s2 on s1.studentId = s2.studentId
where s1.fieldId = 2 and s2.fieldId=3
) t1
group by city, stateabb
) t2 inner join (
select stateAbb, count(stateabb) as stateSubTotal from (
select s1.Response as city, s2.Response as StateAbb
from aaa s1 inner join aaa s2 on s1.studentId = s2.studentId
where s1.fieldId = 2 and s2.fieldId=3
) t3
group by stateabb
) t4 on t2.stateabb = t4.stateabb