I've the following 2 tables:
Players
id name
p1 name1
p2 name2
p3 name3
p4 name4
Matches
id winner loser
m1 p1 p2
m2 p3 p4
what i want is to write a select statement that will return the following:
id name matches wins
p1 name1 1 1
p3 name3 1 1
p2 name2 1 0
p4 name4 1 0
this is basically to return the tournament standings, ordered by number of wins.
One method uses correlated subqueries:
select p.*,
(select count(*) from matches m where p.id in (m.winner, m.loser)
) as matches,
(select count(*) from matches m where p.id = m.winner
) as wins
from players p
order by wins desc;
Another way is to use two outer joins:
select p.id,
p.name,
count(distinct m.id) as matches,
count(distinct w.id) as wins
from players p
left join matches m on p.id in (m.winner, m.loser)
left join matches w on w.winner = p.id
group by p.id, p.name
order by wins desc, p.name
You can add 2 columns to Players table or create new table Tournament named. You can register Tournament Players with your hand(manually) on your admin panel.
If will you add 2 columns to Players table. U will query Players win scores, after query get your MySQL number of rows function and you will get hoe much win The Player. After writenitnto Tournament page. (Note: Sorry for bad English, im trying to speak English. Please try to understand me.)
Related
Newbie question about joining tables. I want to retrieve a name from a column TWICE in a SQL statement, and I'm running in circles.
I Have two Tables - "Company" & "People"
Table -"People"
ID
Name
Phone
1
Luke
555-1212
2
Leia
555-1234
3
Han
999-8888
4
Anikin
888-9876
5
Obi-wan
555-1212
6
R2-D2
#% - **!?
Table - "Company"
ID
CompanyName
PrimaryContact
AltContact
1
Speeders R Us
5
1
2
Droid Repair World
6
4
3
Luke's Second Hand Store
1
4
4
Cloak World
4
5
5
Ye Old Blaster Shoppe
3
2
If I want to get a result that gives BOTH the Contact Names for a Company, How would I do it?
I can get the PrimaryContact to JOIN Properly using something like...
SELECT C.*, P.Name as 'Primary'
FROM `Company` C
Join People P on
C.PrimaryContact = P.ID
WHERE C.ID =3
which successfully returns
ID
CompanyName
PrimaryContact
AltContact
Primary
3
Luke's Second Hand Store
1
4
Luke
But for the life of me, I can't figure out how to modify this SQL to also return "Anikin" as the Alternate Contact. Is this an example of where a UNION statement would help?
You can join to the same table multiple times, just give a new alias every time.
Join People P on C.PrimaryContact = P.ID
Join People P1 on C.AltContact = P1.ID
Join People altcontact on C.AltContact = altcontact.ID
Join People P256 on C.yetanotheralternateContact = P256.ID
You need to to join for ecervy contact another Persons table
SELECT C.ID,C.CompanyName, P.Name as 'Primary' , P.Phone As 'primary_Phone', P2.Name on 'Alternative', P2.Phone as 'Alternatibe_Phone
FROM `Company` C
Join People P on
C.PrimaryContact = P.ID
Join People P2 on
C.AltContact = P2.ID
WHERE C.ID
Update years later:
I came back to answer my own question. I had no idea what an inner join was and apparently completely misused the term here.
I currently have the following 3 tables:
Team
TeamID
Player
PlayerID | TeamID
Match
Player1 | Player2 | Round
I want to write a query showing a match like:
Team1 | Team2
I figured out how to join my tables player and match, so far that works too, but I can't figure out how to replace the player name with the team name. Any idea? I have the following:
SELECT P1.PlayerID AS Player1, P2.PlayerID AS Player2
FROM MATCH
INNER JOIN PLAYER AS P1 ON MATCH.Player1 = P1.PlayerID
INNER JOIN PLAYER AS P2 ON MATCH.Player2 = P2.PlayerID
I've come back to this question years later.
Assuming the following tables:
Team
id | name
Player
id | team_id
Match
player1_id | player2_id | round
The result I wanted was something like
player1's team name | player2's team name | round
I used distinct originally, but distinct is not the correct way to remove duplicates, as Turophile correctly points out.
A better query would be something like
select t1.name, t2.name, m.round
from match as m
left join player as p1 on m.player1_id = p1.id
left join team as t1 on p1.team_id = t1.id
left join player as p2 on m.player2_id = p2.id
left join team as t2 on p2.team_id = t2.id
Please help me regarding query. I am pretty weak in DBMS.
I have a table TBLParent which has some rows as follows
pkParentId FKProductId Name
1 5 P1
2 5 P2
3 3 P3
and I have another table TBLChild that consist of its children
pkId fkParentId ChildName
1 1 C1
2 1 c2
3 2 c1
Now, question is I want Parent records and count of its children based on productId.
For example: I want to
select
TBLParent.pkParentId, TBLParent.FKProductId,
TBLParent.Name,
count of its children
where
TBLParent.FKProductId = 5
I tried like this
Select
count(TBLChild.pkId) AS total,
TBLChild.fkParentId
from
TBLChild
group by
TBLChild.fkParentId
but how can I attach records of parent table with this count?
This will give me count but How I will attach parent record with this count. I mean to say output would be
pkParentId Name Count
1 P1 2
2 P2 1
Please help please help please help?
SELECT P.pkParentId
,P.Name
,COUNT(*)
FROM tblParent P
INNER JOIN tblChild C ON P.pkParentId = C.fkParentId
WHERE P.pkParentId = #yourValueHere
GROUP BY P.pkParentId, P.Name
I am trying to return the fields that have intersecting fields for a specific person. What I mean by this is
Name Friend
---- -----
Joe Sally
Joe Bill
Mary Sally
Mary Michael
Mike Joe
Bill Bill
Bill Sally
Gil Sally
Gil Bill
Gil David
Say, we want the list of people that match Joe's second column, they would have to match Sally and Bill both. So only Bill matches this criteria because Mary has one, but she doesn't have Bill. Gil has Sally and Bill, but he also has David. So only Bill should be returned. I was thinking something with INTERSECT would work because that returns common fields but that wouldn't account for someone having more, I think. Not sure how to write a SQL query to do what I want.
Clearly stated, the list of names that have the same exact friends as Joe.
Without duplicates
SELECT p2.name
FROM people AS p1
JOIN people AS p2 ON p2.number = p1.number
AND p2.name <> p1.name -- exclude self-join
WHERE p1.name = 'Joe'
AND NOT EXISTS (
SELECT 1
FROM people p3
WHERE p3.name = p2.name
AND p3.number <> p1.number
)
GROUP BY p2.name
HAVING count(*) = (SELECT count(*) FROM people WHERE name = 'Joe')
The last condition AND NOT EXISTS ... is only needed if you want to exclude people that have additional friends Joe does not have.
It excludes Gil in your example from the result.
This is a special case of relational division (with a self-referencing table). You can find a whole arsenal of query techniques in this related answer:
How to filter SQL results in a has-many-through relation
With duplicates
If there can be duplicates (like in your first draft of the question), things get a little more complicated:
WITH p AS (
SELECT name, number, count(*) AS ct
FROM people
GROUP BY name, number
)
SELECT p2.name
FROM p AS p1
JOIN p AS p2 ON p2.number = p1.number
AND p2.ct = p1.ct
AND p2.name <> p1.name -- exclude self-join
WHERE p1.name = 'Joe'
AND NOT EXISTS (
SELECT 1
FROM p p3
WHERE p3.name = p2.name
AND p3.number <> p1.number
)
GROUP BY p2.name
HAVING count(*) = (SELECT count(*) FROM p WHERE name = 'Joe')
I have a table which has the id of a particular person and id of the person he likes.
Likes
(p1,p2)
id1,id2
id2,id1
id3,id4
id3 id5
expected output
id1,id2
I have to remove duplicates also meaning id1,id2 to be returned once.
It is a exercise question.
select hh.id, hh.name, hh.grade as gr
, hh.id2, kk.name, kk.grade as gr1
from ( select id, id2, grade, name
from highschooler ab
, Likes cd
where ab.id = cd.id1 ) hh
, highschooler kk
where hh.id2 = kk.id
This query returns something like this
student id,student name,student grade,friend student likes,friend name,friend grade
This should do it joining on itself:
SELECT p.p1, p.p2
FROM Likes p
INNER JOIN Likes p2 ON
p.p1=p2.p2 AND
p.p2=p2.p1 AND
p.p1<p2.p1
Sample Fiddle Demo
I think the nicest way to do this is with a group by. In SQL Server, this requires using a case statement:
with l as (
select (case when p1 < p2 then p1 else p2 end) as pfirst,
(case when p1 < p2 then p2 else p1 end) as psecond
from likes
)
select pfirst, psecond
from l
group by pfirst, psecond
having count(*) = 2
If you have duplicates in the original data, then the having clause should be:
having count(distinct p1) = 2