SQL add columns of each record together - sql

To be blunt I don't know SQL however I don't want the answer, I want to work it out myself.
Here's the question:
Write a SQL query to calculate the number of goals for each team.
players
id name team_id goals
1 Joel 1 3
2 Ed 2 1
3 Simon 2 4
teams
id name
1 New Zealand
2 London
What I'm asking for is an arrow to information that will allow me to solve the question.
I've tried looking myself but I don't even know the correct terminology to ask the question, googling 'write sql to add fields for each row' just seems to return about adding columns or inserting.

You need to first try to JOIN your tables(id in Teams will be linked to TeamId in Players.) based on the foreign key columns.
Then you need to do the GROUP BY and use the aggregate function SUM to get the goals for each team.
So your query will be like:
select t.name, sum(p.goals) as cnt,
from players p inner join teams t on p.teamid = t.id
group by t.name

First you have to group players by teams : use t1.id=t2.id to join values in the tables, and then group theme by "BROUP BY" t.name.
Then : user "SUM(value)" function who sum values .
select teams.name,sum(players.goals) from players,team where player.team_id=teams.id group by teams.name;

Related

SQL Join query brings multiple results

I have 2 tables. One lists all the goals scored in the English Premier League and who scored it and the other, the squad numbers of each player in the league.
I want to do a join so that the table sums the total number of goals by player name, and then looks up the squad number of that player.
Table A [goal_scorer]
[]1
Table B [squads]
[]2
I have the SQL query below:
SELECT goal_scorer.*,sum(goal_scorer.number),squads.squad_number
FROM goal_scorer
Inner join squads on goal_scorer.name=squads.player
group by goal_scorer.name
The issue I have is that in the result, the sum of 'number' is too high and seems to include duplicate rows. For example, Aaron Lennon has scored 33 times, not 264 as shown below.
Maybe you want something like this?
SELECT goal_scorer.*, s.total, squads.squad_number
FROM goal_scorer
LEFT JOIN (
SELECT name, sum(number) as total
FROM goal_scorer
GROUP BY name
) s on s.name = goal_scorer.name
JOIN squads on goal_scorer.name=squads.player
There are other ways to do it, but here I'm using a sub-query to get the total by player. NB: Most modern SQL platforms support windowing functions to do this too.
Also, probably don't need the left on the sub-query (since we know there will always be at least one name), but I put it in case your actual use case is more complicated.
Can you try this if you are using sql-server?
select *
from squads
outer apply(
selecr sum(goal_scorer.number) as score
from goal_scorer where goal_scorer.name=squads.player
)x

sqlite Joins with MAX

I have 2 tables. One displays a game played (Date,Where, result,opponent etc) and the other one the details of a batting innings (runs scored, etc) Both tables have a primary key that relates the batting back to a specific game.
I am trying to return the OPPONENT column from Games when the MAX (highest) score is recorded in the table BATTING, but currently i am unsure how to do this.
The 2 tables can be found here
http://i.imgur.com/bqiyD3X.png
The example from these tables would be (max score is 101 in RUNSSCORED, so return the linked OPPONENT from GAMEINDEX which is "Ferndale"
Any help would be great. Thanks.
Is this what you are looking for?
select OPPONENT
from GAMES
where GAMESINDEX in
(select GAMESINDEX from BATTING order by RUNSSCORED desc limit 1);
If there isn't a unique max RUNSSCORED value, then the answer might not be deterministic.
If you want multiple winners in that case, you could use
select OPPONENT
from GAMES natural join BATTING
WHERE RUNSSCORED in (select MAX(RUNSSCORED) from BATTING);
SELECT G.OPPONENT, MAX(B.RUNSSCORED)
FROM GAMES AS G
INNER JOIN BATTING AS B
ON G.GAMESINDEX = B.GAMESINDEX

SQL JOIN returning multiple rows when I only want one row

I am having a slow brain day...
The tables I am joining:
Policy_Office:
PolicyNumber OfficeCode
1 A
2 B
3 C
4 D
5 A
Office_Info:
OfficeCode AgentCode OfficeName
A 123 Acme
A 456 Acme
A 789 Acme
B 111 Ace
B 222 Ace
B 333 Ace
... ... ....
I want to perform a search to return all policies that are affiliated with an office name. For example, if I search for "Acme", I should get two policies: 1 & 5.
My current query looks like this:
SELECT
*
FROM
Policy_Office P
INNER JOIN Office_Info O ON P.OfficeCode = O.OfficeCode
WHERE
O.OfficeName = 'Acme'
But this query returns multiple rows, which I know is because there are multiple matches from the second table.
How do I write the query to only return two rows?
SELECT DISTINCT a.PolicyNumber
FROM Policy_Office a
INNER JOIN Office_Info b
ON a.OfficeCode = b.OfficeCode
WHERE b.officeName = 'Acme'
SQLFiddle Demo
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
Simple join returns the Cartesian multiplication of the two sets and you have 2 A in the first table and 3 A in the second table and you probably get 6 results. If you want only the policy number then you should do a distinct on it.
(using MS-Sqlserver)
I know this thread is 10 years old, but I don't like distinct (in my head it means that the engine gathers all possible data, computes every selected row in each record into a hash and adds it to a tree ordered by that hash; I may be wrong, but it seems inefficient).
Instead, I use CTE and the function row_number(). The solution may very well be a much slower approach, but it's pretty, easy to maintain and I like it:
Given is a person and a telephone table tied together with a foreign key (in the telephone table). This construct means that a person can have more numbers, but I only want the first, so that each person only appears one time in the result set (I ought to be able concatenate multiple telephone numbers into one string (pivot, I think), but that's another issue).
; -- don't forget this one!
with telephonenumbers
as
(
select [id]
, [person_id]
, [number]
, row_number() over (partition by [person_id] order by [activestart] desc) as rowno
from [dbo].[telephone]
where ([activeuntil] is null or [activeuntil] > getdate()
)
select p.[id]
,p.[name]
,t.[number]
from [dbo].[person] p
left join telephonenumbers t on t.person_id = p.id
and t.rowno = 1
This does the trick (in fact the last line does), and the syntax is readable and easy to expand. The example is simple but when creating large scripts that joins tables left and right (literally), it is difficult to avoid that the result contains unwanted duplets - and difficult to identify which tables creates them. CTE works great for me.

SQL Database SELECT question

Need some help with an homework assignment on SQL
Problem
Find out who (first name and last name) has played the most games in the chess tournament with an ID = 41
Background information
I got a table called Games, which contains information...
game ID
tournament ID
start_time
end_time
white_pieces_player_id
black_pieces_player_id
white_result
black_result
...about all the separate chess games that have taken place in three different tournaments ....
(tournaments having ID's of 41,42 and 47)
...and the first and last names of the players are stored in a table called People....
person ID (same ID which comes up in the table 'Games' as white_pieces_player_id and
black_pieces_player_id)
first_name
last_name
...how to make a SELECT statement in SQL that would give me the answer?
sounds like you need to limit by tournamentID in your where clause, join with the people table on white_pieces_player_id and black_pieces_player_id, and use the max function on the count of white_result = win union black_result = win.
interesting problem.
what do you have so far?
hmm... responding to your comment
SELECT isik.eesnimi
FROM partii JOIN isik ON partii.valge=isik.id
WHERE turniir='41'
group by isik.eesnimi
having count(*)>4
consider using the max() function instead of the having count(*)> number
you can add the last name to the select clause if you also add it to the group by clause
sry, I only speak American. What language is this code in?
I would aggregate a join to that table to a derived table like this:
SELECT a.last_name, a.first_name, CNT(b.gamecount) totalcount
FROM players a
JOIN (select cnt(*) gamecount, a.playerid
FROM games
WHERE a.tournamentid = 47
AND (white_player_id = a.playerid OR black_player_id = a.playerid)
GROUP BY playerid
) b
ON b.playerid = a.playerid
GROUP BY last_name, first_name
ORDER BY totalcount
something like this so that you are getting both counts for their black/white play and then joining and aggregating on that.
Then, if you only want the top one, just select the TOP 1

Retrieving alternate attribute values in GROUP BY query?

Let me explain what I mean with that question:
Lets say I have to tables like these:
customers
id customer location
1 Adam UK
2 Pete US
values
id value
1 10
1 7
2 3
2 41
Let's ignore here for a moment that that (and the following query) wouldn't make a lot of sense. It's meant as a simplified example.
Now, if I run this query
SELECT id, customer, value FROM customers INNER JOIN values GROUP BY id
I should get this result (distinct by id)
id customer value
1 Adam 10
2 Pete 3
What I would like to be able to do is get that to use it in a search result list, but for actual displaying of the results I'd like to do something like this:
Customer: Adam
Values: 10, 7
So, basically, while I need to have a result set that's distinct for the ID, I'd still like to somehow save the rows dropped by the GROUP BY to show the values list like above. What is the best way to do this?
Look at http://mysql.com/group_concat - which only will work in MySql.
Better link: http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html#function_group-concat
Technically, the following is not valid SQL even though MySQL allows it:
Select customers.id, customers.customer, values.value
From customers
Inner Join values
On values.id = customers.id
Group By customers.id
The SQL spec requires that every column in the Select clause be referenced in the Group By or in an aggregate function. However, given what you said later in your post, what I think you want is GROUP_CONCAT as first mentioned by Erik (+1) which is a function specific to MySQL:
Select customers.customer, Group_Concat(values.value)
From customers
Inner Join values
On values.id = customers.id
Group By customers.customer