I need to query a MySQL database table that looks like this:
Bike Owner Date
-----------------------
1 Oscar 2014-02-02
2 Oscar 2014-02-02
3 John 2014-04-28
4 Jane 2014-05-29
2 John 2015-04-16
3 Mike 2015-06-16
1 Bob 2015-07-16
4 John 2015-08-16
2 Mike 2016-04-16
3 John 2016-04-16
It contains 4 bikes and as soon as the bike switches from owner, a new record is placed within this table. Since this table doesn't have an 'until' attribute, I am stuck creating a query that gets all the owners of all bikes at a specific date, say 2015-07-06.
Does anyone now how to do this in an easy way? I can think of ways of doing this by creating functions or temporary tables, but this seems way too far fetched for such an easy question.
Thanks!
One method uses an explicit join and aggregation:
select b.*
from (select bike, max(date) as maxdate
from bikes b
where date <= '2015-07-06
group by bike
) bd join
bikes b
on b.bike = bd.bike and b.date = bd.maxdate;
A somewhat shorter way to write this:
select b.*
from bikes b
where b.date = (select max(b2.date) from bikes b2 where b2.bike = b.bike);
If I understood your requirement correctly then it is very straight foreword query, getting all owner of bike on specific date
select b.*
from bikes b
where CAST(b.date AS DATE) = '2015-07-06'
Related
I'm a bit stuck on this question and was hoping for some help. Here's where I'm at currently.
I have this TEST table of Names. Each Person can either be a recruiter or an employee. The number in Recruited_by is associated with the person_id.
Person_id Name Recruited_by
1 Jean Grayson 1
2 Paul Smith 7
3 John Do Null
4 Alex Lee 7
5 Lisa Kim 7
6 Bob Thompson 3
7 Mike Keen Null
8 Raymond Red 3
9 Alisson Jones 1
10 Kate James 3
Here is the query I have so far which I'm trying to the names of the recruiters that hire more than 3 employees (which will return nothing in this case) and the number of employees that were NOT recruited by anyone (which would be the NULL names).
SELECT T.Name as Employees, COUNT(T1.Name) as Not_hired
FROM Test AS T
WHERE COUNT(T1.Name) IS NULL
LEFT OUTER JOIN Test AS T1
ON T.Recruited_by = T1.Person_id
GROUP BY T.Name
HAVING COUNT(T1.Name) > 3
However this query is returning nothing when I should expect it to return the number of employees who were not hired by a recruiter!
If you want in the results only 1 row with 2 columns then you can do a LEFT join of the table to a query that aggregates to get the ids of the persons that hired more than 3 persons and aggregate again to get the number of persons that were not recruited by anyone:
SELECT GROUP_CONCAT(CASE WHEN t2.Recruited_by IS NOT NULL THEN t1.Name END ORDER BY t1.Name) names,
SUM(t1.Recruited_by IS NULL) total_not_recruited
FROM Test t1
LEFT JOIN (
SELECT Recruited_by
FROM Test
GROUP BY Recruited_by
HAVING COUNT(*) > 3
) t2 ON t2.Recruited_by = t1.Person_id;
You will get the names of the persons that hired more than 3 persons (if they exist) as a comma separated list.
See the demo.
I have four tables like this:
**USERS**
___________________________
user_ID username password
---------------------------
1 user1 1234
2 user2 5678
**TEAMS**
______________________________________
team_ID formation team_name user_ID
--------------------------------------
1 4-4-2 team1 1
2 4-3-3 team2 2
**PLAYERS**
____________________________________
player_ID name position rating
------------------------------------
1 Ronaldo LW 94
2 Messi RW 93
3 Hazard LW 90
**ACTIVE PLAYERS**
___________________________________
ID player_ID team_ID cardview_ID
-----------------------------------
1 1 2 9
2 3 1 7
3 2 1 3
Each user has a team with a formation and a team name. The "active players" tables references the player_ID with the team_ID to see which players are currently active on which teams.
Let's say that user1 logs in to the application, then I want to get all the players name, ratingand their cardview_ID. Something that should look like this:
_____________________________
name rating cardview_ID
-----------------------------
Hazard 90 7
Messi 94 3
These are the players that are currently active on user1's team which is team1.
How can I get this joined table? I have tried with an inner join but that didn't seem to do the work for me.
_______________________________ EDIT_____________________________________
This is the query that doesn't give the desired result:
SELECT players.name, players.rating, activeplayers.cardview_ID
FROM players
INNER JOIN
activeplayers
ON players.player_ID = usedplayers.player_ID
I also tried to join them on team_ID.
Assuming you have the logged in user's ID available, I think this will give you what you're asking for:
SELECT
[PLAYERS].name,
[PLAYERS].rating,
[ACTIVE PLAYERS].cardview_ID
FROM [TEAMS]
JOIN [ACTIVE PLAYERS]
ON [TEAMS].team_ID = [ACTIVE PLAYERS].team_id
JOIN [PLAYERS]
ON [PLAYERS].player_id = [ACTIVE PLAYERS].player_id
WHERE [TEAMS].user_id = <logged_in_user_id>
Please also note the questions asking for clarifying details, and also feel free to respond if this query gets you part of the way but you need more information. The content in angle brackets are of course a placeholder. I also don't know your exact table names so you may need to replace what is in the square brackets with the actual table names.
Assuming that the query in your post contains a typo and is actually this:
SELECT players.name, players.rating, activeplayers.cardview_ID
FROM players
INNER JOIN
activeplayers
ON players.player_ID = activeplayers.player_ID
This query will correctly return all the players who are active players. Now to limit it only to the team for User1, you need to add an additional join to the Teams table, same way you did the join above, and then add a WHERE clause that filters on the Teams.UserID.
That's it.
I have two tables, an Events table and a Category table. The data would look something like this (simplified as I omitted dates):
Events:
Name | catid
John 35
Mary 36
Ed 37
John 38
Tom 39
Mary 40
Category:
catid | category
35 run
35 swim
36 bike
36 swim
36 run
37 bike
38 swim
39 swim
40 run
If you think of each row in the events table as another day we have a person and one or more activities that person performed in the day. Let's say on Sunday John participated in running and swimming the 'catid' in the Events table references the two activities in the Category table.
What I am looking to do is get a table with distinct names and a count of each activity they performed over time. Like this:
Name | run | swim |bike
Ed 1
John 1 2
Mary 1 1
Tom 1
I know I would probably need some JOIN commands but I am not sure how to setup the SQL statement.
Try something like this
SELECT
e.Name,
SUM(CASE WHEN c.Category = 'run' THEN 1 ELSE 0 END) as run,
SUM(CASE WHEN c.Category = 'swim' THEN 1 ELSE 0 END) as swim,
SUM(CASE WHEN c.Category = 'bike' THEN 1 ELSE 0 END) as bike
FROM Events as e
LEFT JOIN Category as c ON c.catid = e.catid
GROUP BY e.Name, e.catid
EDIT: I did not notice that there were 2 Johns in your data set. I have modified the query to fix that. I am also adding a SQL Fiddle to show the changes.
SQL FIDDLE
EDIT2: Query using With ROLL UP with totals row is shown in FIDDLE 2
I think you have some issues with the structure of your database and data therein. If you have a table of categories you should not have catid be repeated for different category names. Might be helpful to get a better handle on the actual structure of the database if you include your code for creating the tables in question.
I am having some major difficulties with grouping and summing results of a query in the way I want. I am having trouble explaining what I want to do in words, so I'll just show you. I have three tables: A, H, and W which look like (simplified):
Table A:
Aid name
1 adam
2 bob
Table H:
Hid Wid date atk Aid
1 1 - 10 2
2 2 - 1 1
3 2 - 5 1
4 1 - 2 2
5 1 - 22 1
6 2 - 7 2
Table W:
Wid name user pass
1 charlie - -
2 donald - -
I am trying to get the SUM of atk grouped by Aid and Wid. Basically, assume this is a fight club tally. I want to display the sum of how many times person W attacked person A (it will always be a one directional fight, ie: charlie can only attack adam, but adam can't attack charlie). (not really a fight club - being used for an online game :))
I am trying to get my result to look like:
name1 atk name2
charlie 22 adam
charlie 12 adam
donald 6 bob
donald 7 bob
My current query looks like...
SELECT w.name AS name1, h.atk, a.name AS name2
FROM H
JOIN W ON w.Wid=h.Wid
JOIN A ON a.Aid=h.Aid
...which gives me every instance that name1 attacked name2. When I try to GROUP BY and/or SUM(h.atk) it is grouping or summing in a way I can't figure out. I'm just not understanding how to accomplish this. Any help would be greatly appreciated.
Thanks in advance!
SELECT w.name AS name1, sum(h.atk) as atk, a.name AS name2
FROM H
JOIN W ON w.Wid=h.Wid
JOIN A ON a.Aid=h.Aid
GROUP BY w.name, a.name
Assume I have 4 tables:
Table 1: Task
ID Task Schedule
1 Cut Grass Mon
2 Sweep Floor Fri
3 Wash Dishes Fri
Table 2: Assigned
ID TaskID (FK) PersonID (FK)
1 1 1
2 1 2
3 2 3
4 3 2
Table 3: Person
ID Name
1 Tom
2 Dick
3 Harry
Table 4: Mobile
ID PersonID (FK) CountryCode MobileNumber
1 1 1 555-555-5555
2 2 44 555-555-1234
3 3 81 555-555-5678
4 3 81 555-555-0000
I'm trying to display the
Task on a certain day
Name of person assigned to task
Phone numbers of said person
I think it should be something like the following, but I'm not sure how to set up the conditions so that the results are limited correctly:
SELECT T.ID, T.Task, P.Name, M.MobileNumber
FROM Task AS T
LEFT JOIN Assigned AS A
ON T.ID = A.TaskID
LEFT JOIN Person AS P
ON A.PersonID = P.ID
LEFT JOIN Mobile AS M
ON M.PersonID = P.ID
WHERE T.Schedule = Fri
My goal is to fetch the following information (it will be displayed differently):
Tasks Name MobileNumber
Sweep Floor, Wash Dishes Dick, Harry 44-555-555-1234, 81-555-555-5678, 81-555-555-0000
Of course, if JOIN is the wrong way to do this, please say so.
It's unclear what you want to do with duplicate data in this case, but you should be looking at using inner joins instead of outer joins, and using something like group_concat() to combine the phone numbers.