How to group two fields together in SQL? - sql

say I have a sql that currently returns all soccer players who has played during each years. Like so:
name year goals
john 2010 1
john 2006 2
john 2006 8
fred 2006 1
But I want the result to be grouped by the years they played, but do not compress player names if they are from different years, like so:
name year goals
john 2010 1
john 2006 10 <--- This is compressed, but there are still 2 johns
fred 2006 1 since they are from different years
say I have done this so far.
(select name, year, goals
from table) as T
If I just do
select *
from
(select name, year, goals
from table) as T
group by year;
Fred will disappear, but if I do "group by name", there are only 1 john left. Any help?

select name, year, sum(goals) as totalgoals
from table
group by name, year

Related

find out the player with highest score in each year

I have a table like these
country
gender
player
score
year
Germany
male
Michael
14
1990
Austria
male
Simon
13
1990
Germany
female
Mila
16
1990
Austria
female
Simona
15
1990
This is a table in the database. It shows 70 countries around the world with player names and gender. It shows which player score how many goals in which year. The years goes from 1990 to 2015. So the table is large. Now I would like to know which female player and which male player score most in every year from 2010 to 2012.
I expect this:
gender
player
score
year
male
Michael
24
2010
male
Simon
19
2011
male
Milos
19
2012
female
Mara
16
2010
female
Simona
16
2011
female
Dania
17
2012
I used that code but got an error
SELECT gender,year,player, max(score) as score from (football) where player = max(score) and year in ('2010','2011','2012') group by 1,2,3
football is the table name
with main as (
select
gender,
player,
year,
sum(score) as total_score -- incase each player played multiple match in a year
from <table_name>
where year between 2010 and 2012
group by 1,2,3
),
ranking as (
select *,
row_number(total_score) over(partition by year, gender order by total_score desc) as rank_
)
select
gender,
player,
year,
total_score
from ranking where rank_ = 1
filter on years
first you add total score, to make sure you cover the cases if there are multiple matches played by the same player in same year
then you create a rank based on year, gender and the total score, so for a given year and for a given gender create a rank
then you filter on rank_ = 1 as it represents the highest score
You can use the dense_rank function to achieve this, if you are using sqlite version 3.25 or higher.
Query
select t.* from(
select *, dense_rank() over(
partition by year, gender
order by score desc
) as rn
from football
where year in ('2010','2011','2012')
) as t
where t.rn = 1;

SQL query all register but select only one of one column [duplicate]

This question already has answers here:
Get top 1 row of each group
(19 answers)
Closed 1 year ago.
Assume that I have one table looking like this:
ID
ClientID
Name
Country
1
JX100
John
Canada
2
JX100
John
Japan
3
JX690
Rob
EUA
4
PX301
Alice
France
And My query:
SELECT DISTINCT ClientID,Name,Country FROM CLIENTS
OUTPUT:
ClientID
Name
Country
JX100
John
Canada
JX100
John
Japan
JX690
Rob
EUA
PX301
Alice
France
I want to take that:
DESIRED:
ClientID
Name
Country
JX100
John
Canada
JX690
Rob
EUA
PX301
Alice
France
TL;DR
I just want to select one country for all Clients, I don't want to get repeated rows.
You can use row_number()over() with common table expression like below:
with cte as (
SELECT DISTINCT ClientID,Name,Country,row_number()over(partition by ClientID ,Name order by Country) rownumber FROM CLIENTS)
select * from cte where rownumber=1
Row_number()over(partition by ClientID ,Name order by Country) will generate a sequence for contries starting from 1 against each clientid and name. So when you will select rownumber=1 this query will select one country for a single clientid,name combination.

Not selecting duplicate records with unique keys

Sample table:
Table Movies:
Title | Year | Price | Genre | ID
Batman 2016 12 Comic 1
Avengers 2014 7 Comic 2
Batman 2016 7 Comic 3
Fast 5 2012 7 Car 4
Superman 5
Star Wars 6
Desired Result:
Title | Year | ID
Batman 2016 1
Avengers 2014 2
Fast 5 2012 4
Superman 5
Star Wars 6
So I need to select distinct ID, Title and Year where Title and Year aren't duplicates. Note Title and Year will always be the same if it is a duplicate so for example Batman 2014 wouldn't be a choice. If it was a duplicate both title and year would be the same as the duplicate record. Basically need to not select duplicate records that have unique keys. What is the most efficient way to do this?
Edit: one other thing. Be aware that null values might be present and I don't want those omitted. I updated the example to show this.
Use a row_number, partition by the distinct fields and order by another
with CTE as
(
select a1.*, row_number() over (partition by Title, Year order by ID) as r_ord
from Movies a1
)
select CTE.*
from CTE
where r_ord =1
or, if you only want the Title, Year and ID:
select Title, Year, min(ID)
from movies
group by Title, Year

SQL statement to select an object that has multiple attributes in the same column

If I were given the following table ATHELTE
PLAYER_NAME SPORT_PLAYED YEAR_PLAYED
---------- ----------- ------------
BOB Basketball 2010
BOB Basketball 2011
BOB Basketball 2012
JOHN Basketball 2010
JOHN Soccer 2011
...
and I want to find a player who has played the same sports across multiple years (in this case it should return BOB since he played basketball for three years) what is the statement to reach the name?
Below is my attempt
SELECT DISTINCT PLAYER_NAME
FROM ATHLETE
HAVING count(YEAR_PLAYED > 1)
But for some reason it returns an empty set
select player_name, sport_played, count(*)
from athlete group by player_name, sport_played having count(*) > 1

How do I get the sum of values from multiple columns in SQL

I have the following table:
Season Name1 Goal1 Name2 Goal2 Name3 Goal3
1990 Smith 2 Abel 1 John 3
1990 Smith 1 Abel 1 John 1
1990 John 0 Smith 2 Abel 5
1991 John 1 Smith 1 Abel 2
1991 Abel 2 John 0 Smith 0
1992 Abel 3 John 0 Smith 1
Season indicates a soccer season, name1, name2 indicates a players position in a given game
Goal1 indicates the number of goals Name1 scored
I would like to generate a list for each name per season how many times they played and the # of goals they scored. Something like this:
Abel 1990 3 games played 7 goals scored
Abel 1991 2 games played 4 goals scored
Abel 1992 1 games played 3 goals scored
John 1990 3 games played 2 goals scored
Any help would be appreciated!
SELECT
sub.player,
sub.Season,
Count(*) AS games_played,
Sum(sub.goals) AS SumOfgoals
FROM
(
SELECT Season, Name1 AS player, Goal1 AS goals
FROM YourTable
UNION ALL
SELECT Season, Name2, Goal2
FROM YourTable
UNION ALL
SELECT Season, Name3, Goal3
FROM YourTable
) AS sub
GROUP BY sub.player, sub.Season
ORDER BY sub.player, sub.Season;
Notice you must use UNION ALL in that subquery. If you use just UNION instead, the subquery result set would include only one row for each combination of Season, player and goals. But when a player scores the same number of goals in more than one game during a season, you want to preserve each of those rows in order to allow an accurate count of games played and total goals scored.
Using your sample data in Access 2007, that query produces this result set.
player Season games_played SumOfgoals
Abel 1990 3 7
Abel 1991 2 4
Abel 1992 1 3
John 1990 3 4
John 1991 2 1
John 1992 1 0
Smith 1990 3 5
Smith 1991 2 1
Smith 1992 1 1
Ok, well, since you aren't sharing what RDBMS you are using, I think that this (ugly) query would work on most of them:
SELECT Name + ' ' + CAST(Season AS VARCHAR(4)) + ' ' +
CAST(Games AS VARCHAR(4)) + ' games played ' +
CAST(Goals AS VARCHAR(4)) + ' goals scored' AS YourColumn
FROM ( SELECT Season, Name, SUM(Goals) AS Goals, COUNT(*) AS Games
FROM ( SELECT Season, Name1 AS Name, Goal1 AS Goals
FROM YourTable
UNION ALL
SELECT Season, Name2 AS Name, Goal2 AS Goals
FROM YourTable
UNION ALL
SELECT Season, Name3 AS Name, Goal3 AS Goals
FROM YourTable) AS A
GROUP BY Season, Name) X
Disclaimer: It is an ugly query.
That's really convoluted, but you could write an in-line query that puts everything into a proper table format so then you can do your usual aggregations and grouping. Keep adding unions for 1 through x, depending on how many columns there are.
SELECT Season, Name, Sum(Goals)
FROM (SELECT Season, Name1 as Name, Goals1 as Goals
FROM table
UNION
SELECT Season, Name2 as Name, Goals2 as Goals
FROM table
UNION
SELECT Season, Name3 as Name, Goals3 as Goals
FROM table) newtable
GROUP BY Season, Name