I have two tables.
Table Emp
id name
1 Ajay
2 Amol
3 Sanjay
4 Vijay
Table Sports
Sport_name Played by
Cricket ^2^,^3^,^4^
Football ^1^,^3^
Vollyball ^4^,^1^
Now I want to write a query which will give me output like
name No_of_sports_played
Ajay 2
Amol 1
Sanjay 2
Vijay 2
So what will be Mysql query for this?
I agree with the above answers/comments that you are not using a database for what a database is for, but here is how you could calculate your table from your current structure in case you have no control over that:
SELECT Emp.name, IF(Played_by IS NULL,0,COUNT(*)) as Num_Sports
FROM Emp
LEFT JOIN Sports
ON Sports.Played_by RLIKE CONCAT('[[:<:]]',Emp.id,'[[:>:]]')
GROUP BY Emp.name;
See it in action here.
UPDATE: added the IF(Played_by IS NULL,0,COUNT(*)) instead of COUNT(*). This means that if an employee doesn't play anything they'll have a 0 as their Num_Sports. See it here (I also added in those ^ characters and it still works.
What it does is joins the Emp table to the Sports table if it can find the Emp.id in the corresponding Played_by column.
For example, if we wanted to see what sports Ajay played (id=1), we could do:
SELECT *
FROM Emp, Sports
WHERE Sports.Played_by LIKE '%1%'
AND Emp.id=1;
The query I gave as my solution is basically the query above, with a GROUP BY Emp.name to perform it for each employee.
The one modification is the use of RLIKE instead of LIKE.
I use RLIKE '[[:<:]]employeeid[[:>:]]' instead of LIKE '%employeeid%. The [[:<:]] symbols just mean "make sure the employeeid you match is a whole word".
This prevents (e.g.) Emp.id 1 matching the 1 in the Played_by of 3,4,11,2.
You do not want to store your relationships in a column like that. Create this table:
CREATE TABLE player_sports (player_id INTEGER NOT NULL, sport_id INTEGER NOT NULL, PRIMARY KEY(player_id, sport_id));
This assumes you have an id column in your sports table. So now a player will have one record in player_sports for each sport they play.
Your final query will be:
SELECT p.name, COUNT(ps.player_id)
FROM players p, player_sports ps
WHERE ps.player_id = p.id
GROUP BY p.name;
Related
I'm blocked with a query and I'm needing some help.
If someone could help me I'd appreciate a lot :)
I have two tables (I'm using only one movie for showing the situation):
Table Consumption
client_id movie_id name date_consumption
XXX 1 MovieA 01/Jan/2000
YYY 1 MovieA 01/Jan/2000
ZZZ 1 MovieA 02/Jan/2000
XXX 1 MovieA 02/Jan/2000
ZZZ 1 MovieA 10/Jan/2000
Table movies_owners
movie_id rightowner date_buyed*
A LucasFilm 01/Jan/2000
A Disney 02/Jan/2000
A Sony 05/Jan/2000
**Date_buyed : It's the date where the movie belongs to a new right owner.*
The ideia is simple:
I have to find the count of clients who watched a movie for day with
the correct Right Owner in the day this movie was watched.
Table Expected
movie_id date_consumption rightowner consumption(count)
MovieA 01/Jan/2000 LucasFilm 2
MovieA 02/Jan/2000 Disney 2
MovieA 10/Jan/2000 Sony 1
--
With this query I can find the correct right owner of the movie in some day (max of all buyed dates before the day in question):
SELECT A.movie_id, A.date_buyed, A.rightowner
FROM movies_owners A
WHERE A.date_buyed EXISTS (
SELECT max(date_buyed)
FROM movies_owners
WHERE TO_DATE(date_buyed) <= TO_DATE('2000-01-02') AND movie_id = 'MovieA')
AND movie_id = 'MovieA';
But my problem is when joing with the consumption table.
I can't use the date_consumption from table consumption in a sub query.
I tried to break into a auxiliar table for doing the join, but I still can't find the result. =\
Can someone has, at least, an ideia or suggestion for me please?
Thank you all in advanced.
Juste for info: I'm working with Hive, but the sintax is almost the same from Sql.
Hive does not support non-equijoins. Move join on c.consumption_date<=o.date_buyed condition to the WHERE clause:
select c.movie_id, c.date_consumption, o.rightowner, c.consumption_count
from
(--consumption count per movie, date
select substr(movie_id,6) movie_id, date_consumption, count(*) consumption_count
from consumption
group by substr(movie_id,6), date_consumption
)c
left join movies_owners o on c.movie_id=o.movie_id
where c.consumption_date<=o.date_buyed
To make it more clear, If I have this data in MySql:
name | allowance | age
----------------------
khan | 50 | 20
aal | 60 | 22
hyme | 50 | 21
khan | 61 | 20
notice that there are two 'khan' in the database with different allowance. I want to only show the name and the age but if I show it using the mysqli select statement, there would be two 'khan' but I only want to show only 1 'khan'. How can I do it?
You need to use GROUP_CONCAT to see agges of all Khans;
select name, GROUP_CONCAT(age) ages from Table group by name
or for minimum aged khan
select name , min(age) MiniumAge from Table group by name
or for elder khan
select name , max(age) MaxAge from Table group by name
or any khan
select name , age from Table group by name
.
Please try below query:-
SELECT name, age FROM table_name WHERE group by name
If you want any from multiple same record then simply used group by query.
I think you could do this:
SELECT name, age FROM table_name WHERE group by name,age
First thing: if both those "khan"s are the same person with two different allowances then your schema is not properly normalized and it will give you big troubles later - imagine you want to change "khan" to "Khan" - now you have to update it in multiple places instead once. Depending on your actual needs you may want one table of people (person_id, name, age), and table of allowances (person_id, allowance, [..some other parameters?..]).
Second, to really get what you want, either you use group by, to get one "random" row per each name as suggested in other answers, or you can do
SELECT DISTINCT name, age FROM table;
which will give you one row per each name-age combination, so khan-20 will be there only once - but if there were khan-25 then that is probably different person and you would have two khans returned, each with their own age.
You can try this mate:
SELECT DISTINCT
name, age
FROM
<your_table>;
or this one
SELECT
name, age
FROM
<your_table>
GROUP BY
name;
Q: Is there any chance that if there are 2 records of tha same name have difference value of age? If so, kindly update the question so that better answers will be given. Cheers!
I got a quick question that has been bugging me. How can I combine a column in two different table into a single column
Example of table:
Employee
emp_no emp_name
1 frieza
2 bulma
3 goku`
gender
emp_no emp_gender
1 unknown
2 female
3 male
I want to combine column emp_name and emp_gender into one column like this:
column emp_name_gender:frieze,bulma,goku,unknown,female,male
Been trying to format this question so it easy to understand, but it takes my time while im doing my work. so im apologize for this simple format question.
It's a join, but with a group_concat or two thrown in.
select concat(group_concat(emp_name), ',', group_concat(emp_gender))
from employee
inner join gender
on employee.emp_no = gender.emp_no
Or if you don't really want it all into a single column and row it would just be
select concat(emp_name, ',', emp_gender)
from employee
inner join gender
on employee.emp_no = gender.emp_no
demo here
What about a UNION :
SELECT emp_name AS emp_name_gender ◄─
FROM employee
UNION ◄█■■
SELECT emp_gender AS emp_name_gender ◄─
FROM gender
You get exactly the result you ask for :
There's a comment from pala_ that worths to answer.
So, I have a table with 3 columns, of which the first column consists of IDs and the last column consists of dates. What I need is, to sort the table by dates, and remove any duplicate IDs with a later date (and keep the ID with the earliest date).
For example,
This is how my table originally looks like -
123 Ryan 01/01/2011
345 Carl 03/01/2011
123 Lisa 01/02/2012
870 Tiya 06/03/2012
345 Carl 07/01/2012
I want my resultant table to look like this -
123 Ryan 01/01/2011
345 Carl 03/01/2011
870 Tiya 06/03/2012
I'm using VBA Access Code to find a solution for the above, and used SQL Queries too, however my resultant table either has no duplicates whatsoever or displays all the records.
Any help will be appreciated.
This will create a new table:
SELECT tbl.SName, a.ID, a.BDate
INTO NoDups
FROM tbl
INNER JOIN (
SELECT ID, Min(ADate) As BDate
FROM tbl GROUP BY ID) AS a
ON (tbl.ADate = a.BDate) AND (tbl.ID = a.ID);
I have a table of money owed, along with a team identifier (could be 1,2,3 for example)
I have another table which gives a name to these team identifiers (so 1 could refer to Team1, 2 could refer to John's jokers etc)
The first table can have multiple entries for money owed and I need to get the total owed per team identifier, and use the team name if it exists.
So I left join the tables and use a sum clause and get a total amount owed per teamname, or null if the teamname is not present. If it is null then I want to use the team identifier, so the results would look like
name total
.....................
team1 100
John's jokers 1000
99 50
where 99 is a team identifier because there was no teamname and there was a null present.
I tried using ifnull(columnName, teamID) but this failed when using a sum clause.
Could anyone help with this problem please
I think ifnull() is used like this:
select ifnull(teams.team_name, teams.team_id) from teams;
So in this case it tries to retrieve the name of the team, and if that comes back null it instead uses the team's identifier. In this case your query would look like this:
select ifnull(teams.team_name, owing.team_id), sum(amount_owed)
from owing left join teams on owing.team_id = teams.id
group by owing.team_id
Make sure the group by asks for the ID field from owing, not teams, otherwise you'll be grouping on a null field.
Does this resolve the issue?