Query specific fields in 3 tables-PHPMyAdmin - mysql

I have four tables (university, statistics, address, records)
University table has the following: (UName, Web Address, ID, (serves as PK)
Statistics: UniversityID, Division, 2012RankPosition,2011 RankPosition,2010 RankPosition,2009 RankPosition
Address: UniversityID, City, State, Zip code
Records: IDUniversity, Wins, Losses, Draw
I want to find all division 2 schools in New York and have their zip codes displayed as well. Can someone help me with this please? I am stuck.
Also, I want to find all division 2 schools that ranked in the top 10 for the past 4 seasons.
If someone has any input i would greatly appreciate it.

First query try this... but i dont know if division 2 = new york...
Select *
FROM University
JOIN Address on University.id = Address.UniversityID
JOIN Statistics on University.id = Statistics.UniversityID
WHERE Statistics.Division = 2
Second query depends on how you have stored the ranking ... if its just number 1 - best , 2,3 etc are worser
Select *
FROM University
JOIN Statistics on University.id = Statistics.UniversityID
WHERE Statistics.Division = 2
AND 2012RankPosition <= 10
AND 2011RankPosition <= 10
AND 2010RankPosition <= 10
AND 2009RankPosition <= 10
Hope that helps

Related

SQL: Find closest number to given value with ties

I'm trying to find the closest number(s) to a given value in SQL. I have already made my query for multiple results:
SELECT *
FROM Cars
ORDER BY ABS(price - $price)
I know I can limit the table by using LIMIT 1, by which I have one number closest to the given value. But how can I include ties? Like for example when there are three or four cars with the same price? The amount of cars which have the same price is dynamic, so I can't specify a certain LIMIT.
I also know I could use SELECT TOP 1 WITH TIES, but I can't use this query because my database driver doesn't allow it. Does anybody have another idea of how to accomplish this?
Example:
car 1 = 2000
car 2 = 3000
car 3 = 3000
car 4 = 1500
When I want the cars closest to 3000, the query should return:
car 2
car 3
But without using a static LIMIT in the query, because the amount of cars with the same price can be different every time. Thanks
If your driver supports nested queries:
SELECT *
FROM CARS
WHERE ABS(price - $price) = ( SELECT MIN(ABS(price - $price)) FROM CARS )

sum in mysql than group by

I am making a small lottery game for fun and to improve myself.
On the database, I have
table(id, package, value, price, purchase_code,round)
See an example. There is two package, package1 and package2.
package1 has a value of 3 and package2 has a value of 4. This means, that if I buy the package1, i got 3 ticket which is playing, giving me bigger chance to win in the current round, so it inserts 3 record into a table, containing the informations. So in this case, I have the following records in my table:
id pacakage_id value price purchase_code round
1 1 3 10 w3hjkrw 1
2 1 3 10 w3hjkrw 1
3 1 3 10 w3hjkrw 1
I would like to see overall how money the users spent , and for this, I used sum(price).
Ok, but as you can see, the three record was one purchase, so sum(price) would give me the result 30. I tried to group by purchase_code, but it is not doing what I want.
Here is the code:
$income_query = mysql_query("SELECT SUM(price) FROM lottery WHERE round = '$current_round' GROUP BY code") or die(mysql_error());
while($result = mysql_fetch_array($income_query)) {
$round_money = $result['SUM(price)']." $";
Think you will need to do a sub query to get the package id price. Possibly using distinct, although I would just use a normal aggregate function (MAX will do the job here).
Something like this:-
SELECT code, SUM(package_id_price)
FROM(
SELECT code, package_id, MAX(price) AS package_id_price
FROM lottery
WHERE round = '$current_round'
GROUP BY code, package_id
) Sub1
GROUP BY code

Relational Database Logic

I'm fairly new to php / mysql programming and I'm having a hard time figuring out the logic for a relational database that I'm trying to build. Here's the problem:
I have different leaders who will be in charge of a store anytime between 9am and 9pm.
A customer who has visited the store can rate their experience on a scale of 1 to 5.
I'm building a site that will allow me to store the shifts that a leader worked as seen below.
When I hit submit, the site would take the data leaderName:"George", shiftTimeArray: 11am, 1pm, 6pm (from the example in the picture) and the shiftDate and send them to an SQL database.
Later, I want to be able to get the average score for a person by sending a query to mysql, retrieving all of the scores that that leader received and averaging them together. I know the code to build the forms and to perform the search. However, I'm having a hard time coming up with the logic for the tables that will relate the data. Currently, I have a mysql table called responses that contains the following fields,
leader_id
shift_date // contains the date that the leader worked
shift_time // contains the time that the leader worked
visit_date // contains the date that the survey/score was given
visit_time // contains the time that the survey/score was given
score // contains the actual score of the survey (1-5)
I enter the shifts that the leader works at the beginning of the week and then enter the survey scores in as they come in during the week.
So Here's the Question: What mysql tables and fields should I create to relate this data so that I can query a leader's name and get the average score from all of their surveys?
You want tables like:
Leader (leader_id, name, etc)
Shift (leader_id, shift_date, shift_time)
SurveyResult (visit_date, visit_time, score)
Note: omitted the surrogate primary keys for Shift and SurveyResult that I would probably include.
To query you join shifts and surveys group on leader and taking the average then jon that back to leader for a name.
The query might be something like (but I haven;t actually built it in MySQL to verify syntax)
SELECT name
,AverageScore
FROM Leader a
INNER JOIN (
SELECT leader_id
, AVG(score) AverageScore
FROM Shift
INNER JOIN
SurveyResult ON shift_date = visit_date
AND shift_time = visit_time --depends on how you are recording time what this really needs to be
GROUP BY leader ID
) b ON a.leader_id = b.leader_id
I would do the following structure:
leaders
id
name
leaders_timetabke (can be multiple per leader)
id,
leader_id
shift_datetime (I assume it stores date and hour here, minutes and seconds are always 0
survey_scores
id,
visit_datetime
score
SELECT l.id, l.name, AVG(s.score) FROM leaders l
INNER JOIN leaders_timetable lt ON lt.leader_id = l.id
INNER JOIN survey_scores s ON lt.shift_datetime=DATE_FORMAT('Y-m-d H:00:00', s.visit_datetime)
GROUP BY l.id
DATE_FORMAT here helps to cut hours and minutes from visit_datetime so that it could be matched against shift_datetime. This is MYSQL function, so if you use something else you'll need to use different function
Say you have a 'leader' who has 5 survey rows with scores 1, 2, 3, 4 and 5.
if you select all surveys from this leader, sum the survey scores and divide them by 5 (the total amount of surveys that this leader has). You will have the average, in this case 3.
(1 + 2 + 3 + 4 + 5) / 5 = 3
You wouldn't need to create any more tables or fields, you have what you need.

Count, max, and multiple sub querys SQL

I'm currently working on a league systeme for my sport team. A ladder, as seen as in some video games.
It's a mobile web site, allowing coaches to create games, and monitor players performances.
I have games automatically balanced, taking into accounts player's experiences and points, then, i give bonus points to the all the players of the winner team, and remove points from the losers.
I have a relatively simple database. 3 tables.
User : id - name
Games : id - ETA - cration_date
game_joueur: id- id_game - id_joueur - team - result - bonus
game_joueur beeing an assoc table, in wich i register for each new game players id, the team he has been seeded on, and afterwards, update the bonus field with the points earned and the result field with an integer (1 = lose, 2= win)
That way i can sum the bonus on my players stat and get the total points.
You can have a better look at the table here :
http://sqlfiddle.com/#!2/d3e06/2
What i'm tryng to acomplish is for each player's stat page, retrieve from the database the name of his most succesfull partner( the guy wich whom he won the most games), and also his worst ally , the men he lost the most match with.
This is what i do on my user stat page :
SELECT
(SELECT COUNT(lad_game_joueur.result) FROM lad_game_joueur WHERE result = 1 AND lad_game_joueur.id_joueur = lad_user.id) as lose,
(SELECT SUM(lad_game_joueur.bonus) FROM lad_game_joueur WHERE lad_game_joueur.id_joueur = lad_user.id) as points,
lad_user.id as id ,
(SELECT COUNT(lad_game_joueur.result) FROM lad_game_joueur WHERE lad_game_joueur.id_joueur = lad_user.id AND result =2) as win,
lad_user.name
FROM lad_user,lad_game_joueur
WHERE lad_game_joueur.id_joueur = lad_user.id AND lad_user.id
='.$id_joueur.'
GROUP BY lad_user.id
ORDER BY puntos DESC
I'm sure this is not the best way to do it, but it works :) ( i'm no sql specialist)
How can i tune this query to also retrive the informations i'm looking for?
I wont mind doing another query.
Thanks a lot in advance!
Ben
Ok i finealy found a way.
Here's what i did :
SELECT
SUM(result)as result_sum, sum(Bonus) as bonus_sum, id_joueur
from lad_game_joueur
where result= 2
and id_game in
(SELECT lad_game_joueur.id_game from lad_game_joueur,lad_game where id_joueur=2
AND result= 2 and lad_game_joueur.id_game=lad_game.id)
group by id_joueur
order by result_sum DESC, bonus_sum desc
As you see, the sum of result would give me 4 if i won two games with the person, but i just divide by 2 on php and voilĂ  :)

Getting scores from MySQL - better option than sub-queries?

I'm building a website for a friend (kind of a hobby thing, not for anything pro/work related) that'll store information about players, games and scores. I have built most of the reporting/statistical info but I want to display how many times a player hit the max score and am wondering if I can improve my idea (based on sub-queries). My 'scores' table is set out as so:
scores (id, gameID, playerID, venueID, versusID, score1, score2, score3, score4, score5, total, seasonID) - all the xID's are foreign keys.
The premise is that a new entry is made per game, per player so I have PHP insert data from text fields etc. This means that say there's 20 games in a season and for score1 'John Smith' hits the max score of 10 4 times that season. But he also hits it 8 times on score2, 6 times on score3 etc (and obviously, these could be in different games). So at the end of the season, I have a big table with a load of results in (I'd have 240 rows given there's 12 players per team) and when I'm looking at my stats, I want to find out how many times John Smith hit a 10 that season. I can obviously do 5 queries (or 1 with sub-queries) and add the results to tell me this, but I'm wondering what's the best method (or the one the 'SQL guru' would use, if you like) purely for my own development.
So to finish: I'm hoping to run my query and get a resultset that tells me:
Name | Total
John Smith | 12
Rob Smith | 11
Will Smith | 11
etc... | 1
The firstName and secondName are stored in the 'player' table (which is linked to the 'scores' table by the playerID foreign key). I'd like to be able to modify the query later on-demand if I wish, for example if I wanted to see how many times players scored a 9 rather than a 10 (but that can obviously be done by passing the number via PHP).
Searching here (+ Google) has lead me down the 'JOIN' route but I've not had much success. Any help, please? :)
I think this should do the trick:
SELECT playerID, COUNT(playerID) AS Total FROM (
SELECT playerID FROM scores WHERE score1='10'
UNION ALL
SELECT playerID FROM scores WHERE score2='10'
UNION ALL
SELECT playerID FROM scores WHERE score3='10'
UNION ALL
SELECT playerID FROM scores WHERE score4='10'
UNION ALL
SELECT playerID FROM scores WHERE score5='10'
) AS thetable
GROUP BY playerID
Where 10 is the score you want.
This will get the playerID with respective number of 10 scores:
select
playerID,
count(score1 = 10 or null) +
count(score2 = 10 or null) +
count(score3 = 10 or null) +
count(score4 = 10 or null) +
count(score5 = 10 or null)
as total
from scores
group by playerID
having total > 0
Join it to the player table to get the names.