How to retrieve same column twice from one table with Where condition - sql

I am trying to retrieve a column twice from one table for ex:
select M.Event_Name as 'Male',
F.Event_Name as 'Female'
from Table1 M, Table1 F
where M.Gender = 'M'
and F.Gender = 'F'
and F.Country = 12
and M.Country = 12
Table1 data
ID Event_Name Gender Country
1 Cricket M 12
2 FootBall M 13
3 BasketBall M 12
4 Hockey M 12
5 Tennis M 13
6 Volly Ball M 13
7 Cricket F 13
8 FootBall F 13
9 BasketBall F 12
10 Hockey F 13
11 Tennis F 12
12 Volly Ball F 12
What I Got is :
Male Female
Cricket Tennis
Cricket BasketBall
Cricket Volly ball
BasketBall Tennis
BasketBall BasketBall
BasketBall Volly ball
Hockey Tennis
Hockey BasketBall
Hockey Volly ball
Expecting:
Male Female
Cricket Tennis
BasketBall BasketBall
Hockey Volly ball
Help me out.. Thanks

You should be able to use something like this which incorporates a PIVOT:
select M as Male,
F as Female
from
(
select event_name, gender,
row_number() over(partition by gender, country order by id) rn
from yourtable
where gender in ('M', 'F')
and country = 12
) src
pivot
(
max(event_name)
for gender in (M, F)
) piv
See SQL Fiddle with Demo
Or you can use an aggregate function with a CASE statement:
select
max(case when gender = 'M' then event_name end) male,
max(case when gender = 'F' then event_name end) female
from
(
select event_name, gender,
row_number() over(partition by gender, country order by id) rn
from yourtable
where gender in ('M', 'F')
and country = 12
) src
group by rn
See SQL Fiddle with Demo
Both produce the same result:
| MALE | FEMALE |
---------------------------
| Cricket | BasketBall |
| BasketBall | Tennis |
| Hockey | Volly Ball |

Related

Select unique countries with more than one customer

I need to show the countries that have more than one individual.
Customers
customer_id first_name last_name age country
1 John Doe 31 USA
2 Robert Luna 22 USA
3 David Robinson 22 UK
4 John Reinhardt 25 UK
5 Betty Doe 28 UAE
So the query should return
customer_id first_name last_name age country
1 John Doe 31 USA
2 Robert Luna 22 USA
3 David Robinson 22 UK
4 John Reinhardt 25 UK
I tried tis query but it didn't work.
SELECT last_name, Country
FROM Customers
GROUP BY Country
HAVING COUNT(Customer_id) > 1;
The actual table can be found here
Try using the following query. Thanks
SELECT * FROM CUSTOMERS C
WHERE C.COUNTRY IN (SELECT COUNTRY FROM CUSTOMERS GROUP BY COUNTRY HAVING COUNT(*)>1)
You could use a windowed count as a filter:
with c as (
select *, Count(*) over(partition by country) cnt
from Customers
)
select *
from c
where cnt > 1;

howw to make rating for each actor , separately for male and female customers?

the exercise is:
Report the number of movie rentals and the average rating for each actor, separately for male and female customers.
Report only actors with more than 5 movie rentals.
code:
SELECT a.name, c.gender,
COUNT(*) AS number_views,
AVG(r.rating) AS avg_rating
FROM renting as r
LEFT JOIN customers AS c
ON r.customer_id = c.customer_id
LEFT JOIN actsin as ai
ON r.movie_id = ai.movie_id
LEFT JOIN actors as a
ON ai.actor_id = a.actor_id
GROUP BY a.name ___ -- For each actor, separately for male and female customers
HAVING AVG(r.rating) IS NOT NULL
where movie_id > 5 -- Report only actors with more than 5 movie rentals
ORDER BY avg_rating DESC, number_views DESC;
how to make rating for each actor, separately for male and female customers?
renting table
renting_id
customer_id
movie_id
rating
date_renting
1
41
8
null
2018-10-09
2
10
29
10
2017-03-01
customers table
customer_id
name
country
gender
date_of_birth
date_account_start
2
Wolfgang Ackermann
Austria
male
1971-11-17
2018-10-15
3
Daniela Herzog
Austria
female
1974-08-07
2019-02-14
actor table
actor_id
name
year_of_birth
nationality
gender
1
Abbie Cornish
1982
Australia
female
2
Adam Sandler
1966
USA
male
actsin table
actsin_id
movie_id
actor_id
1
37
1
2
56
2

How to group by Max?

I'm having some trouble with a statement,
I have a table like this
Player Number
Sport
Date
1
soccer
4/1
4
basketball
4/2
2
basketball
4/3
3
soccer
4/1
1
baseball
4/2
4
basketball
4/3
5
soccer
4/1
3
baseball
4/2
5
soccer
4/2
2
basketball
4/3
1
soccer
4/4
2
baseball
4/5
3
soccer
4/4
4
soccer
4/5
5
soccer
4/3
5
basketball
4/5
I'm trying to write a query that will give me a table that will group together the players by their most played sport so the end result will look like this:
Sport
# of Players Who played the sport the most
Baseball
2
Basketball
1
Soccer
2
I was able to write a statement that shows the number of times each player played a a specific sport but am having trouble getting the table to only select the rows with the highest number of plays and arranging it to be grouped by each sport.
Select distinct PLAYER_NUMBER, SPORT, Max(GAMES_PLAYED) as GAMES_PLAYED
FROM #temp
Group By SPORT, PLAYER_NUMER
order by GAMES_PLAYED desc
I don't think your desired results match your sample data?
Anyway start with a query to get the number of plays per player, and use the row_number window function to determine which sport was played the most for each player (note what do you want to do in the case of a tie?). Then in the next query only use the sport with the most plays per player and group by sport.
with cte as (
select *
-- For each player get the sport with the most plays
, row_number() over (partition by Player order by count(*) desc) rn
from #temp
group by Player, Sport
)
select Sport
, count(*) [# of Players Who played the sport the most]
from cte
where rn = 1
group by Sport
order by Sport;
Returns:
Sport
# of Players Who played the sport the most
basketball
2
soccer
3
The following related query allows one to confirm the results shown above:
with cte as (
select *
, count(*) num
, row_number() over (partition by Player order by count(*) desc) rn
from #temp
group by Player, Sport
)
select Player, Sport, num
from cte
order by Player, num desc;
Which shows for each player which sport was played the most i.e. its the first row for each player, and note baseball never shows up as the most played sport! The actual results are calculated using every rn=1 because that is the sport most played per player.
Player
Sport
num
rn
1
soccer
2
1
1
baseball
1
2
2
basketball
2
1
2
baseball
1
2
3
soccer
2
1
3
baseball
1
2
4
basketball
2
1
4
soccer
1
2
5
soccer
3
1
5
basketball
1
2
If I understand you right, you might also get this by subqueries
select s.sport,
count(distinct s.playdate) as times_played,
(select max(t.players) from (
select count(distinct s2.player) as players
from sports s2
where s2.sport = s.sport
group by s2.sport, s2.playdate
) t
) as nbr_players
from sports s
group by s.sport
this gets me
sport
times_played
nbr_players
baseball
2
2
basketball
3
2
soccer
5
3
DBFiddle here

Remove records based on priority in sql server

details table
name age sports
john 27 football
john 27 cricket
john 27 basketball
kyle 28 baseball
kyle 28 football
nick 24 football
nick 24 hockey
ron 35 football
Priority table :
name priority
futsal 1
basketball 2
football 3
cricket 4
baseball 5
hockey 6
desired table :
name age sports
john 27 basketball --as basketball has the highest priority for john
kyle 28 baseball
nick 24 football
ron 35 football
What is desired is that i want to keep only 1 record for a name and rest should be deleted based on priority of sports .
I know to delete duplicate records but can anyone suggest me can this be accomplished in sql server and
how!!
Do the join use row_number():
select t.*
from (select d.name, d.age, d.sports,
row_number() over (partition by d.name order by p.priority) as seq
from details d inner join
priority p
on p.name = d.sports
) t
where seq = 1;
You can use window functions. Here is one method:
select dp.*
from (select d.*, min(p.priority) over (partition by d.name)
from details d join
priorities p
on d.sport = p.name
) dp
where seqnum = 1;

Group columns in query

I have a query where I fetch the following columns:
ID Name Age Hobby
ID, name and age comes from Table A
Hobby comes from Table B
Example of results I can get is the following:
ID Name Age Hobby
0 John 35 Fishing
0 John 35 Tennis
0 John 35 Hiking
1 Jane 31 Fishing
2 Nate 42 Fishing
2 Nate 42 Tennis
What I would like to have as result is the following instead:
ID Name Age Hobby
0 John 35 Fishing, Tennis, Hiking
1 Jane 31 Fishing
2 Nate 42 Fishing, Tennis
Any ideas of how to achieve that?
Try this :
;WITH CTE AS(
SELECT DISTINCT ID,NAME,AGE
FROM TableName
)
SELECT *,
STUFF(SELECT ','+ Hobby FROM TableName t1 WHERE t1.ID=CTE.ID FOR XML PATH(''),1,1,'')
FROM CTE