Grouping Sql Tables - sql-server-2008

I have three tables which i have joined ..but the manner in which i have to display them is a little difficult for me to understand.I am trying to group them and not getting the desired result.
Sports_Name
Id | Name
---------
1 Football
2 Cricket
3 Hockey
4 Tenis
Teams
Id | Sport_Id | Team_Name
----------------------------
101 1 Manchester United
103 2 Australia
104 2 India
109 1 Real Madrid
110 3 New Zeland
Player_Name
Id | Team_Id | Player_Name
------------------------------
1 101 Rooney
2 104 Tendulkar
3 103 Ponting
4 109 Ronaldo
5 101 Van Persie
6 110 Simond
I need to display this information in the following manner..
**Football**
Manchester United -Rooney
Manchester United -Van Persie
Real Madrid -Ronaldo
**Cricket**
India-Tendulkar
Australia-Ponting
**Hockey**
New Zeland -Simond
and something similar for tenis
See this picture for details

Is this what you want?
SELECT sports_name.name, teams.team_name, player_name.player_name FROM player_name
JOIN
teams ON
player_name.team_ID = teams.ID
JOIN
sports_name on
sports_name.id = teams.sport_id
order by sports_name.name, team_name
This gets all the data in order then you just need to use your presentation layer to use sports.name as group header.
This produces
name team_name player_name
Cricket Australia Ponting
Cricket india Tendulkar
Football Man u Rooney
Football Man u RVP
Football Real Madrid Ronaldo
Hockey N Z Simond

try this:
SELECT T.TEAM_NAME+' - '+ P.PLAYER_NAME as 'FOOTBALL'
FROM TEAMS T JOIN PLAYER_NAME P
ON T.ID=P.TEAM_ID
JOIN SPORTS_NAME S
ON T.SPORT_ID=S.ID
WHERE S.NAME='FOOTBALL'
Change the where clause to 'Cricket','Hockey' to get other results

The basic query would be something like:
SELECT s.Name, t.Name, p.Player_Name
FROM Player_Name p
INNER JOIN Teams t
ON t.Id = p.Team_id
INNER JOIN Sports_Name s
ON s.Id = t.Sport_Id
Then if you want to display the results like you described it, my guess would be to use a cursor. Use parameterized procedure to add a WHERE clause to the query in order to filter the results by sport's name.

Related

How to order by from third table (related to Max(), join)

Let me explain the question with the following example: (long but easy to understand)
This is how my MySQL database looks like:
table name: general_info
Movie_ID movie_title
1 Iron Man
2 Superman
3 Batman
table name: cast
Movie_ID Cast_Name
1 Robert Downey Jr.
1 Gwyneth Paltrow
2 Henry Cavill
2 Amy Adams
3 Christian Bale
3 Heath Ledger
Table name production_companies
Movie_ID Production_name
1 Marvel
1 Paramount
2 Legendary Pictures
2 DC Entertainment
3 Snycopy
table name user_cast_preference
user_id user_cast_name user_cast_rating
1 Robert Downey Jr. 95
1 Gwyneth Paltrow 45
1 Christian Bale 80
1 Heath Ledger 90
table name user_production_preference
user_id user_production_name user_production_rating
1 Marvel 85
1 Paraamount 70
1 Syncopy 65
Now, I am able to fetch all movies that are in user's preferred cast + preferred production company, using this query
select general_info.movie_id,movie_title from general_info
inner join cast on general_info.movie_id = cast.movie_id
inner join production_companies on general_info.movie_id = production_companies.movie_id
where cast.cast_name in (select user_cast_name from user_cast_preference)
or production_companies.production_companie_name in (select user_production_name from user_production_preference)
group by movie_title
Current Result:
movie_id moive_title
3 Batman
1 Iron Man
Only batman and Ironman got fetched because at least one of the actor or production company was involved in it (which is also in user's preferred list)
Till now everything is just fine. But I want to do this:
I want to order movies by this algorithem.
I will compare all fetched movies with the given rating in my tables and order them by Top to bottom.
In my case, let's compare Batman and Iron Man.
This is how, I decided to compare.
Take the top rated cast from Ironman + Top rated production company from iron man
Take the top rated cast from Batman + Top rated production company from batman
that is:
95 (iron man) + 85 (marvel) = 180
90 (heath ledger) + 65 (syncopy) = 155
Now Iron man has more rating than Batman, so expected result will be:
movie_id moive_title total_rating
1 Iron Man 180
3 BatMan 155
I hope, I made myself clear.
You want all movies where the user either have an actor or a company (or both) in their preferences. Then you want to sort by the sum of top preferences.
I'd look up the maximum points of user-rated casts and maximum points of user-rated companies per movie first and then outer join these aggregation results to the movie table:
select gi.*
from general_info
left join
(
select c.movie_id, max(ucp.user_cast_rating) as points
from cast c
join user_cast_preference ucp on ucp.user_cast_name = c.cast_name
where ucp.user_id = 1
group by c.movie_id
) p1 on p1.movie_id = gi.movie_id
left join
(
select pc.movie_id, max(upp.user_cast_rating) as points
from production_companies pc
join user_production_preference upp on upp.user_cast_name = pc.cast_name
where upp.user_id = 1
group by pc.movie_id
) p2 on p1.movie_id = gi.movie_id
where p1.points > 0 or p2.points > 0
order by coalesce(p1.points, 0) + coalesce(p2.points, 0) desc;
Not sure where you are getting "production_companies.production_companie_name" in your original code
SELECT general_info.Movie_ID,
general_info.movie_title,
MAX(user_cast_preference.user_cast_rating + user_production_preference.user_production_rating) AS total_rating
FROM ((((general_info
INNER JOIN CAST ON general_info.Movie_ID = cast.Movie_ID)
INNER JOIN production_companies ON cast.Movie_ID = production_companies.Movie_ID)
INNER JOIN user_production_preference ON production_companies.Production_name = user_production_preference.user_production_name)
INNER JOIN user_cast_preference ON cast.Cast_Name = user_cast_preference.user_cast_name)
GROUP BY movie_title
ORDER BY total_rating DESC;

How to write SQL query using a join on 3 tables?

I have created a hypothetical scenario with some dummy data. Below are 3 basic tables and I'm looking to write a query to find what property/properties Mary has viewed.
In this scenario Mary has viewed 1 property a flat in Glasgow.
Table 1: Client
=====================
ID Name
=====================
5 Tom
6 Mary
7 John
Table 2: Property
=====================
ID CITY TYPE
=====================
14 Aberdeen House
16 Glasgow Flat
21 Glasgow House
94 London Flat
Table 3: Viewing
========================
Client Property Date
========================
5 14 01-12-2016
5 21 08-12-2016
6 16 10-10-2016
Definitely use inner joins for this, a quick example of this could be
SELECT c.Name, p.Type, p.City, v.Date
FROM Viewing v
JOIN Client c ON v.client = c.ID
JOIN Property p ON v.property = p.ID
WHERE c.Name = 'Mary'
That should show you who view what and when. I've used aliases on the table names just to keep it neat.

How to multiple concatenate values from multiple relation tables in a single mysql query

I have a big issue for my "traveling offer" project, working 99% OK, but not 100%.
I have main table with offers, where each offer can have set multiple department cities as well as multiple destination cities (this is reduced sample with reduced columns).
For example, I'm offering some travels from England, where department cities can be from London, Leeds and Manchester. Destination cities are Prague, Bratislava, Budapest and Belgrade.
Offer 1 is set to department cities London or Leeds, and destinations are Prague and Budapest.
Offer 2 is set to department city London, and destinations are Bratislava and Belgrade.
Offer 3 is set to department city Manchester or Leeds, and destination is Prague.
Table offers
----------------------------
id title price
----------------------------
1 Offer 1 title 300 Eur
2 Offer 2 title 250 Eur
3 Offer 3 title 350 Eur
Now relation tables and city name tables
Table departments
----------------------------
id name
----------------------------
1 London
2 Leeds
3 Manchester
relation Table rel_departments
------------------------
offer_id rel_id
------------------------
1 1
1 2
2 1
3 2
3 3
Table destinations
----------------------------
id name
----------------------------
1 Prague
2 Bratislava
3 Budapest
4 Belgrade
relation Table rel_destinations
------------------------
offer_id rel_id
------------------------
1 1
1 3
2 2
2 4
3 1
As SQL result I expect for each offer concatenated values bot for department cities and destination cities
If I search all with following sql I got OK result:
SELECT offers.*,
GROUP_CONCAT(DISTINCT DEPC.name SEPARATOR ', ') AS depCities,
GROUP_CONCAT(DISTINCT DESTC.name SEPARATOR ', ') AS destCities
FROM offers
INNER JOIN `rel_departments` ON (`rel_departments`.`offer_id` = `offers`.`id`)
INNER JOIN `departments` as DEPC ON (DEPC.`id` = `rel_departments`.`rel_id`)
INNER JOIN `rel_destinations` ON (`rel_destinations`.`offer_id` = `offers`.`id`)
INNER JOIN `destinations` as DESTC ON (DESTC.`id` = `rel_destinations`.`rel_id`)
GROUP BY offers.id
result would be okay:
---------------------------------------------------------------------
id title price depCities destCities
---------------------------------------------------------------------
1 Offer 1 title 300 Eur London, Leeds Prague, Budapest
2 Offer 2 title 250 Eur London Bratislava, Belgrade
3 Offer 3 title 350 Eur Leeds, Manchester Prague
And I need results like this whatever WHERE clause is. But, whenever I put where clause, I loose one of results in concatenation. For example, I search for all offers with Prague as a destination. If I add to the end of the sql statement:
where rel_destinations.rel_id=1
result is as following:
---------------------------------------------------------------------
id title price depCities destCities
---------------------------------------------------------------------
1 Offer 1 title 300 Eur London, Leeds Prague
3 Offer 3 title 350 Eur Leeds, Manchester Prague
If you can notice, there is no Budapest in offer 1. What to do to get complete concatenation string... Not that WHERE clause can be more complex, i.e. to search for department city or any other parameter.
Any help is appreciated :)
You need to use a different join with rel_destinations to get the offers with Prague as a destination. Join this with your original query.
SELECT offers.*,
GROUP_CONCAT(DISTINCT DEPC.name SEPARATOR ', ') AS depCities,
GROUP_CONCAT(DISTINCT DESTC.name SEPARATOR ', ') AS destCities
FROM offers
INNER JOIN `rel_departments` ON (`rel_departments`.`offer_id` = `offers`.`id`)
INNER JOIN `departments` as DEPC ON (DEPC.`id` = `rel_departments`.`rel_id`)
INNER JOIN `rel_destinations` ON (`rel_destinations`.`offer_id` = `offers`.`id`)
INNER JOIN `destinations` as DESTC ON (DESTC.`id` = `rel_destinations`.`rel_id`)
INNER JOIN rel_destinations AS d1 ON d1.offer_id = offers.id
WHERE d1.rel_id = 1
GROUP BY offers.id
DEMO

MySQL join tables for counts with multiple conditions

Trying to create a report across 3 tables - company, account, user. For each company, there's an ID in account. Each user has an account. I can get totals easily enough, but I need to add count of how many users out of the total are registered (username is not null).
SELECT c.c_name, c.c_groupnumber, count(a.a_userid) AS TotalCount
FROM company c
LEFT JOIN account a ON c.c_groupnumber = a.a_groupnumber
WHERE a.a_deleted IS NULL
GROUP BY c.c_groupnumber
HAVING TotalCount > 0;
How can I add in a condition that gives me a count of user.u_username not null while maintaining my TotalCount? The link between account and user is
a.a_userid = user.u_userid
tbl.company
c_id, c_groupnumber, c_name
1 1234 widgets, inc.
2 5678 joe's garage
tbl.user
u_userid, u_username, u_name
1 bill Bill Smith
2 frank Frank Johnson
3 NULL Jane Doe
4 mary Mary Stack
5 NULL Steve Spot
tbl.account
a_id, a_userid, a_groupnumber
100 1 1234
101 2 5678
102 3 5678
103 4 1234
104 5 1234
So using the above very simplified table example, company "Widget's Inc." has 3 employees (bill smith, mary stack and steve spot), and of those 3 2 have registered (bill and mary), while steve has not (username is null).
Joe's Garage has 2 employees - Frank and Jane, and Frank has registered, while Jane has not.
I'd love to generate a report something like this:
Group Company Total Emp Reg Emp
1234 Widgets Inc 3 2
5678 Joe's Garag 2 1
Hopefully that makes the question clearer?
What if you get the count of username and then perform a JOIN with that like
SELECT c.c_name, c.c_groupnumber, count(a.a_userid) AS TotalCount,
xxx.username_count
FROM company c
LEFT JOIN account a ON c.c_groupnumber = a.a_groupnumber
LEFT JOIN ( select u_userid, count(u_username) username_count
from `user`
group by u_userid ) xxx ON a.a_userid = xxx.u_userid
WHERE a.a_deleted IS NULL
GROUP BY c.c_groupnumber
HAVING TotalCount > 0;

how to get multiple items in one line in mysql?

I have an employees table, which has all the information about employees, including the manager_id, for example:
id name manager_id
1 Joe 5
2 Mary 5
3 Bill 5
4 Jane 6
5 Matt 6
6 Walt 7
I would like to get a list of people, and for each one all their direct reports. Is it possible to create a query to give me the following output:
Employee Direct Reports
Joe
Mary
Bill
Jane
Matt Joe, Bill, Mary
Walt Jane, Matt
This way:
SELECT s.name AS employee, group_concat( e.name )
FROM employees s
LEFT OUTER JOIN employees e ON s.id = e.manager_id
GROUP BY s.id
You have to join the table with itself. And you need to use left join, so that you get the employees who don't manage anyone.