SQL- selecting two id's who share something in common - sql

I have a table that has player_id, team_id
I want to find all players who played on the same 3 or more teams.
The expected output would be :
player1, player2, number_of_teams
so far i have something like
SELECT player_id as player1, player_id as player2, count(team_id) as number_of_teams
FROM player_history
WHERE ....
Sample Data:
player_id | team_id
--------------------
001 | 23
001 | 15
001 | 21
002 | 23
002 | 21
002 | 15
002 | 34
003 | 23
003 | 15
003 | 34
003 | 21
004 | 12
004 | 11
004 | 23
should return:
player1 | player2 | number_of_teams
-----------------------------------
001 | 002 | 3
001 | 003 | 3
002 | 003 | 4

What you should do is join your table with itself, on the same team but different players, once found, you should group the result table and count
Since I assume there's more than 2 players in each team and you're looking for different players in the same year as implied (not really specified) in your question, I took the liberty to add it to the join conditions
You can, of course, remove it
SELECT
p1,
p2,
COUNT(team_id) as total
FROM
(
SELECT
h1.team_id,
h1.player_id as p1,
h2.player_id as p2
FROM
player_history h1
INNER JOIN player_history h2 ON h1.team_id = h2.team_id AND h1.player_id != h2.player_id AND h1.year = h2.year
GROUP BY
h1.team_id,
h1.player_id
) sameteam
GROUP BY
p1,
p2
HAVING
total >= 3
Notice that your example result doesn't fit the example data. play 4 should not be on the list
SQLFiddle here
hope it helps

Related

Sql join does not return some rows with groupBy

I am trying to learn sql.I do some practices.I created a table which called Student.
Id | Name | Amount
1 | Jone | 100
2 | Jack | 200
3 | Emily | 300
4 |Haaland | 500
7 |Ted | 700
I also created Orders table like that:
Id | Name | Amount | Dıscount
1 | Jone | 100 | 10
2 | Jack | 112 | 20
3 | Emily | 300 | 30
4 |Haaland | 500 | 50
5 |Jack | 88 | 12
7 |Ted | 150 | 235
My query is:
select a1.Id Id ,a1.Name Name, a1.Amount Amount , sum(a2.discount)
from student a1
left outer join orders a2
on a1.Id=a2.Id
and a1.Name=a2.Name
and a1.Amount = a2.Amount
group by a1.Id, a1.Name, a1.Amount
Result:
Id | Name | Amount | Dıscount
1 | Jone | 100 | 10
3 | Emily | 300 | 30
4 |Haaland | 500 | 50
2 | Jack | 200 | null
7 | Ted | 700 | null
I get null value for the jack row.I have to use a1.Amount=a2.Amount because I remove amount constraint Ted'discount also appears.
Expected Result :
Id | Name | Amount | Dıscount
1 | Jone | 100 | 10
3 | Emily | 300 | 30
4 |Haaland | 500 | 50
2 | Jack | 200 | 32
7 | Ted |700 | null
I think the logic you want is to pre-aggregate the orders of each name in a subquery, then join by name and amount:
select s.id , s.name, s.amount, o.discount
from student s
left join (
select name, sum(amount) amount, sum(discount) discount
from orders
group by name
) o on o.name = s.name and o.amount = s.amount
What is the confusion? In one row you have:
id name amount
2 Jack 200
And in the other:
id name amount
2 Jack 112
Your join requires equality on all three columns. The amounts don't match, so there is no match for Jack's row and the amount is null.
Your question is not clear on what you actually want to do, so I'll stop here.
The amount for Jack does not match (200 in Student, 88 and 112 in Orders), so nothing can be joined ON a1.Amount = a2.Amount for that record. However, Please be advised that even if one of the values in Amount does match, the GROUP BY function will still not know which Amount you want associated with 'Jack'.

SQL Select - Get a count of data as a separate column error

I am working on this query whereas I have a table as follows
Code | Date
-------------
001 | 20-JUN
001 | 20-JUN
002 | 20-JUN
003 | 20-JUN
002 | 20-JUN
001 | 20-JUN
002 | 21-JUN
I need to get a count of codes in a separate column only for the date of 20-JUN
Code | Count
--------------
001 | 3
002 | 2
003 | 1
Here's the query I am trying.
SELECT
ll.code,
(
SELECT
COUNT(*)
FROM
lab_tests ltb
WHERE
ltb.code = ll.code
AND ltb.date = ll.date
) AS Count
FROM
lab_tests ll
WHERE
ll.date = '20-JUN'
This however does not give me the desired outcome, except it returns this.
Code | Count
--------------
001 | 1
001 | 1
001 | 1
002 | 1
002 | 1
003 | 1
I still cannot figure out how to change the query to get the outcome I need. Can anyone please help?
Thanks in advance!
You seem to just want aggregation:
select t.code, count(*) cnt
from mytable t
where t.date = date '2020-06-20'
group by t.code
This assumes that date is stored as a date, and that your database, which you did not tell, supports the standard syntax to declare literal dates.

Finding out Percentage Value using Hive

I have some tables as:
Table_1:
+------------+--------------+
| Student_ID | Student_Name |
+------------+--------------+
| 000 | Jack |
| 001 | Ron |
| 002 | Nick |
+------------+--------------+
Table_2:
+-----+-------+-------+
| ID | Total | Score |
+-----+-------+-------+
| 000 | 100 | 80 |
| 001 | 100 | 80 |
| 002 | 100 | 80 |
+-----+-------+-------+
Table_3:
+-----+-------+-------+
| ID | Total | Score |
+-----+-------+-------+
| 000 | 100 | 60 |
| 001 | 100 | 80 |
| 002 | 100 | 70 |
+-----+-------+-------+
Expected_Output:
ID percent
000 70
001 80
002 75
I have created a hive table before. Now, I want to come up with a single HiveQL so that, I can get the expected output from these above 3 tables.
What I am thinking to do is, in my query I will:
use the Left outer join using ID
find the sum of "Total" and "Score" for each ID
divide sum of "Score" by sum of "Total" to get percentage.
I came up with this:
INSERT OVERWRITE TABLE expected_output
SELECT t1.Student_ID AS ID, (100*t4.SUM1/t4.SUM2) AS percent
FROM Table_1 t1
LEFT OUTER JOIN(
SELECT (ISNULL(Total,0) + ISNULL(Total,0)) AS ‘SUM2’, (ISNULL(Score,0) + ISNULL(Score,0)) AS ‘SUM1’
FROM t4
)ON (t1.Student_ID=t2.ID) JOIN Table_3 t3 ON (t3.ID=t2.ID);
And, I am stuck at this point. Not sure how to reach to the result.
Any idea please?
This is a simple join. Assuming you have one row per id in each of tables t2 and t3, you can do
SELECT t2.Student_ID AS ID, 100.0*(t2.score+t3.score)/(t2.total+t3.total) AS percent
FROM Table_2 t2
JOIN Table_3 t3 ON t3.ID=t2.ID

MS Access: Finding the top of each group in an SQL query

In my table, I have four columns.
I have a player name, an ID, an age, and a score.
ID | Player Name | Age | Score
------------------------------
0 | James | 24 | 20
1 | Carly | 24 | 25
2 | Matt | 24 | 19
3 | Jess | 26 | 35
4 | Jimmy | 26 | 32
5 | Tom | 27 | 19
6 | Brian | 27 | 25
I need to write a query to find the top player of each age group, but I am stumped. I've tried sorting both and using the Max() function, and I have tried manually looping through the values to find the top, but with no avail.
This is the sort of result I'd expect:
ID | Player Name | Age | Score
------------------------------
1 | Carly | 24 | 25
3 | Jess | 26 | 35
6 | Brian | 27 | 25
I am quite confused, and I'm sure there's a simple way to achieve this. Thanks.
One way to solve this is to create an inline view of the max scores per age and then join to it
SELECT p.*
FROM players p
INNER JOIN (SELECT age,
Max(score) as mScore
FROM players
GROUP BY age) AS mp
ON p.age = mp.age
AND p.score = mp.mscore
You should note that if there is tie for max more than one record can appear per age

Sum of count from external table

I need to search for the sum of the games made by specific developers. I have two tables:
_____________________________
|____________GAMES____________|
| Id | Title | id_dev | hits |
| 01 | abc | 1 | 20 |
| 02 | xyz | 2 | 15 |
| 03 | cde | 1 | 9 |
_______________
|__DEVELOPERS___|
| Id | Title |
| 01 | poi |
| 02 | asd |
| 03 | qwe |
I want result formatted like Developers title 40, where 40 is the sum of all hits of the games with the ID of this developer. How can I go about this?
SELECT developers.title, COUNT(count) AS total FROM (SELECT COUNT(games.hits) AS count
FROM games
GROUP BY id_dev
HAVING count > 1) as A
FROM developers
JOIN games
WHERE developers.id = games.id_dev
This is a simple join and aggregate, so you are overcomplicating things:
select d.id, d.title, sum(g.hits)
from games g join
developers d
on g.id_dev = d.id
group by d.id, d.title;