I have four tables:
tournaments (id, name, slots, price, gameId, platformId)
games (id, name)
platforms (id, name)
participations (id, tournamentId, playerId)
I want to get tournament's game name, platform name, slots, price, reservedSlots (participations count), information whether some player (his id is provided by php) participate in this tournament (bool/true) and conditions are:
- gameId must be in specified array provided by php
- platformId must be in specified array provided by php
I have created something like this but it doesn't work correctly:
php:
$platformsList = "'". implode("', '", $platforms) ."'"; //
$gamesList = "'". implode("', '", $games). "'";
mysql:
SELECT
t. NAME AS tournamentName,
t.id,
t.slots,
p. NAME,
g. NAME AS gameName,
t.price
FROM
tournaments AS t,
platforms AS p,
games AS g,
participations AS part
WHERE
t.PlatformId = p.Id
AND t.GameId = g.Id
AND t.Slots - (
SELECT
count(*)
FROM
participations
WHERE
TournamentId = t.id
) > 0
AND part.TournamentId = t.Id
AND t.PlatformId IN ($platformsList)
AND t.GameId IN ($gamesList)
I will not dwelve into handling your post and get values, I will assume that everything is all right:
$possibleGameIDs = getPossibleGameIDs(); //function will return the array you need for possible game id values. Inside your function make sure that the id values are really numeric
$possiblePlatformIDs = getPossiblePlatformIDs(); //function will return the array you need for possible platform id values. Inside your function make sure that the id values are really numeric
$playerId = getPlayerId(); //function returns the player id and makes sure that it is really a number
$sql = "select games.name, platforms.name, tournaments.slots, tournaments.price, ".
"(select count(*) from participations where participations.tournamentId = tournaments.tournamentId) as reservedSlots, ".
"(select count(*) > 0 from participations where participations.tournamentId = tournaments.tournamentId and playerId = ".$playerId.") as isParticipating ".
"from tournamens ".
"join games ".
"on tournaments.gameId = games.id ".
"join platforms ".
"on tournaments.platformId = platforms.id ".
"where games.id in (".implode(",", $possibleGameIDs).") and ".
" platforms.id in (".implode(",", $possiblePlatformIDs).") and ".
" tournaments.slots > 0"
Code was not tested, so please, let me know if you experience any problems using it. Naturally you need to run it, but as you did not specify what do you use to run the query, I did not allocate time to deal with technical details of running it. Beware SQL injections though.
Related
I have a MySQL database in which there is a table that serves as a master list of representative names ids and his/her respective manager, a table that serves as a list of managers, and four additional tables which serve as time intervals in which daily sales data is recorded (calls taken, time taken after each call, revenue, envelopes, pens and other). I am attempting to gather all the statistics for each representative under a single given manager, four times in a day. My thinking is that I should first gather the names and ids under a given manager, and then use that array(?) to run a query through the various tour intervals to gather the sales statistics. What is the best way to do this?
<?php
include 'db_connect.php';
// Get last name of manager
$query = "SELECT * FROM managers WHERE id = '" . $_SESSION['manager_name'] ."';";
$result = $mysqli -> query($query);
$row = $result -> fetch_array(MYSQLI_NUM);
$manager_first = $row[1];
$manager_last = $row[2];
// Get team members
$rep_query = "SELECT * FROM rep_master WHERE leader = '" . $manager_last . "';";
$rep_list = array();
$rep_result = $mysqli -> query($rep_query);
if ($rep_result) {
while ($rep_row = $rep_result -> fetch_row()) {
array_push($rep_list, $rep_row[1] . " " . $rep_row[2]);
}
};
sort($rep_list);
print_r($rep_list);
// Stat query (using my ID as a testing point)
$stat_query = "SELECT id, total_calls, acw, revenue, envelopes, pens, other FROM tour_1 WHERE id='T441241';";
// Get row data
$stat_row = $stat_result -> fetch_array(MYSQLI_NUM);
echo '<br /><br />';
print_r($stat_row);
?>
Use IN and implode:
print_r($rep_list);
// Stat query (using my ID as a testing point)
$stat_query = "SELECT id, total_calls, acw, revenue, envelopes, pens, other
FROM tour_1 WHERE id IN(".implode(",",$rep_list).")";
Assuming your tour tables all have the same structure, you could use UNIONs on the four shift tables and two LEFT JOINs to do this in a single query. I've added a column to show which tour the info came from. Here, it's not clear how you want to group and filter the statistics, so you may get multiple rows with the same leader and rep. You can add GROUP BY modifiers within the combinedtours nested query and WHERE filters or ORDER BY modifiers at the appropriate locations to optimise the query and group, filter and order the records accordingly.
SELECT `managers`.*, CONCAT(`rep_master`.`first_name`, ' ', `rep_master`.`last_name`), combinedtours.* FROM `managers`
RIGHT JOIN
`rep_master` ON `rep_master`.`leader` = `managers`.`last_name`
LEFT JOIN
(SELECT id, 1 as tour, total_calls, acw, revenue, envelopes, pens, other FROM tour_1
UNION
SELECT id, 2 as tour, total_calls, acw, revenue, envelopes, pens, other FROM tour_2
UNION
SELECT id, 3 as tour, total_calls, acw, revenue, envelopes, pens, other FROM tour_3
UNION
SELECT id, 4 as tour, total_calls, acw, revenue, envelopes, pens, other FROM tour_4
) combinedtours
ON combinedtours.`id` = `rep_master`.`rep_id`
I have a table that displays books. However I would like only only 1 book to be shown per unique email address (strContactEmail). I tried the below query, it didn't work. Any help greatly appreciated.`
$sql = "SELECT lngbookid, strTitle, strAuthor, strcoursecode, strISBN, ".
" strcontactname, DISTINCT(strContactEmail) AS strContactEmail, ".
" curPrice, ysnsalerent, dtmpostdate, memcomments, school, ".
" ASIN, BookIMG, ISBN10, ISBN13, Updated, ".
" datetime, user_ip, NoOtherBooks ".
" FROM tblbooks ".
" WHERE strcoursecode LIKE '%$search%' ".
" ORDER BY datetime DESC LIMIT 50";
Try a GROUP BY statement:
http://www.w3schools.com/sql/sql_groupby.asp
The easiest way:
SELECT max(lngbookid) as lngbookid,
max(strtitle) as strtitle,
max(strauthor) as strauthor,
max(strcoursecode) as strcoursecode,
max(strisbn) as strisbn,
max(strcontactname) as strcontactname,
strcontactemail,
max(curprice) as curprice,
max(ysnsalerent) as ysnsalerent,
max(dtmpostdate) as dtmpostdate,
max(memcomments) as memcomments,
max(school) as school,
max(asin) as asin,
max(bookimg) as bookimg,
max(isbn10) as isbn10,
max(isbn13) as isbn13,
max(updated) as updated,
max(datetime) as datetime,
max(user_ip) as user_ip,
max(nootherbooks) as nootherbooks
FROM tblbooks
WHERE strcoursecode LIKE '%$search%'
GROUP BY strcontactemail
ORDER BY datetime DESC
LIMIT 50
EDIT
Well, the above was actually too "dummy". Better way to do this is (providing that column "lngbookid" is a primary key):
SELECT a.lngbookid,
a.strtitle,
a.strauthor,
a.strcoursecode,
a.strisbn,
a.strcontactname,
a.strcontactemail,
a.ontactemail,
a.curprice,
a.ysnsalerent,
a.dtmpostdate,
a.memcomments,
a.school,
a.asin,
a.bookimg,
a.isbn10,
a.isbn13,
a.updated,
a.datetime,
a.user_ip,
a.nootherbooks
FROM tblbooks AS a
JOIN (SELECT strcontactemail,
Max(lngbookid) AS lngbookid
FROM tblbooks
GROUP BY strcontactemail) AS b
ON ( a.strcontactemail = b.strcontactemail
AND a.lngbookid = b.lngbookid )
Basically this script exports all of the orders in our little system to a CSV file. There are 4 separate tables that are joined to complete this. SEorder, SEtracking, SE_user, users_orders.
Here is the error:
<div id="Error">An error occurred in script '/home/sites/mywebsite.com/web/administration/allorders.php' on line 81:
<br />Undefined index: UserLast
Here is my database query:
//Make the query-select all orders
$query2 ="SELECT DISTINCT o.OrderID, Basket, Title, FirstName, LastName, Suffix, Company, Address1, Address2, City, State, Zip, GiftCard, GiftCardMsg, t.Tracking, u.UserFirst, u.UserLast AS doo ".
"FROM SEorder o ".
"LEFT JOIN SEtracking t ON (o.OrderID = t.OrderID) ".
"INNER JOIN users_orders uo ON (uo.OrderID = o.OrderID) ".
"INNER JOIN SEuser u ON (u.UserID = uo.UserID) ".
"AND Submitted='Y' ".
"ORDER BY OrderDate ASC";
and here is my php to grab the data. this is line 81 that is throwing the error:
$username = $row['UserFirst'] . " " . $row['UserLast'];
I am positive that the table SEuser exists, has the column UserLast, and that column has data in it. I am not completely versed on JOIN's though so am I missing something here? I did not create this script, just troubleshooting. Thanks!
It looks like you aliased the UserLast column as doo.
because you have queried the UserLast as doo
so use the doo index not UserLast
u.UserLast AS doo
Your PHP should say $row['doo']
I am trying to search zipcodes matchin in area of 25 miles.
lets say I got 10 zip codes from my function that holds true.
now I have my value in a variable like this:
$zip_res = A0A 1B0, A0A 1G0, ...
column name is postal_code.
How can I match all values at once with postal_code?
I can not use loop, I have to do it in one time.
any suggestions are welcome.
Edit
MySQL statement where $zip_res is used
$sql= "SELECT distinct(p.id), p.extra FROM practitioner p INNER JOIN practitioner_category pc ON pc.practitioner_id = p.id AND pc.category_id = ";
$sql .= "'" .$this->category. "' ";
$sql .= "AND p.primary_postal_code in " .$zip_res. " WHERE 1 AND p.status = 1 ";
It looks like you're just looking for the IN keyword:
SELECT * FROM TABLE_NAME WHERE POSTAL_CODE IN ($zip_res);
Just as a note, however, you need to be able to quote all of those items first. So you might do this before using the above query:
$zip_res = "'" . str_replace(',',"','",$zip_res) . "'";
You can try to use
select ... from ... where postal_code ALL($zip_res).
But I'm not sure because of in accordance to manual you should use subqueries.
See http://dev.mysql.com/doc/refman/5.5/en/all-subqueries.html
I have 2 tables; members and teams
members table
memberID, firstName, lastName
(firstName and lastName are fulltext indexes)
teams table
team_id, member1ID, member2ID
Here's my query
$sql = "SELECT a.* ";
$sql .= "FROM teams a WHERE ";
$sql .= "a.member1ID IN (SELECT b.memberID FROM members b ";
$sql .= "WHERE MATCH(b.firstName, b.lastName) AGAINST('$q' IN BOOLEAN MODE)) ";
$sql .= "OR a.member2ID IN (SELECT b.memberID FROM members b ";
$sql .= "WHERE MATCH(b.firstName, b.lastName) AGAINST('$q' IN BOOLEAN MODE)) ";
if($year)
$sql .= "AND a.team_y = $year ";
$sql .= "ORDER BY a.team_num ASC ";
if($limit)
$sql .= "$limit";
This query has to be close, but its not working yet.
Im trying to build a query that will let me show me all of the teams "$q" is on.
Ex. $q=doe , Show me all teams that doe is on.
This query has to output the teams.
One possible reason your query doesn't work is there is a minimum length on full-text searching, which defaults to 4 characters. "doe" would fail this match. You can increase this via variable "ft_min_word_len"
http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_ft_min_word_len
By the way, if you want to avoid Normalizing (which isn't always the "best" way to go), you could at least use JOIN's instead of sub-selects.. e.g. (field names renamed to save on typing)
select t.* from teams t
inner join members me1 on t.m1 = me1.id
inner join members me2 on t.m2 = me2.id
where MATCH(me1.fname, me1.lname, me2.fname, me2.lname)
AGAINST('smith' IN BOOLEAN MODE);
Normalize your database.
In your case, this would mean having a table Team (team_id, name, whatever else), a table Member (member_id, first_name, last_name), and a table MemberToTeam (member_id, team_id). In other words, move the member1ID and member2ID into their own table.
Following this practice, apart from "improving" your database schema in the general sense, means that the query that bothers you will become trivial to write.
If you know the member_id:
SELECT team_id FROM MemberToTeam WHERE member_id = 1
If you search by first or last name:
SELECT mtt.team_id FROM Member m
LEFT JOIN MemberToTeam mtt ON m.member_id = mtt.member_id
WHERE m.first_name LIKE '%your search string here%' OR m.lastname LIKE '%your search string here%'