I added the line AND t.cover='$c' and now it will not show any results. However, all variables are correct. If I run the line in phpMyAdmin it will display the results fine. Am I missing syntax in PHP? If I remove the t.cover='$c' the script works fine on the web. $c is simply a $_GET['c'] that will either be empty or will equal 0, which I redefine to 'No'.
if($t != '') {
if($c == 'No') {
$getListings = mysql_query("SELECT * FROM events t LEFT JOIN bars b on t.venue=b.name WHERE t.date='$date' AND t.type='$t' AND t.cover='$c' AND b.active='1' ORDER BY t.promoted DESC, t.order ASC");
} else {
$getListings = mysql_query("SELECT * FROM events t LEFT JOIN bars b on t.venue=b.name WHERE t.date='$date' AND t.type='$t' AND b.active='1' ORDER BY t.promoted DESC, t.order ASC");
}
} else {
if($c == 'No') {
$getListings = mysql_query("SELECT * FROM events t LEFT JOIN bars b on t.venue=b.name WHERE t.date='$date' AND t.cover='$c' AND t.type='$t' AND b.active='1' ORDER BY t.promoted DESC, t.order ASC");
} else {
$getListings = mysql_query("SELECT * FROM events t LEFT JOIN bars b on t.venue=b.name WHERE t.date='$date' AND b.active='1' ORDER BY t.promoted DESC, t.order ASC");
}
}
My biggest confusion is why it works in phpMyAdmin but yet displays no rows on the web.
It seems I have tried everything on Google and still no luck. I wish it would throw an error or something to point me in a direction, but it just comes up as though the query was empty. If anyone has any idea, I am still looking for input. Maybe LEFT JOIN is doing it?
...LEFT JOIN bars b on t.venue=b.name AND b.active=1 ...
Remove the b.active from the WHERE otherwise it will be a condition for the SELECT
The current queries have SELECT... WHERE ... b.active = 1 ... meaning it can only return results where that condition is met
Related
I have 3 queries which I run which are nearly identical, the latter two have an AND condition.
Main query:
$mess = $mysqli->prepare("SELECT * from ( SELECT cm.id ,cm.userid,cm.message,cm.voteup,cm.votedown,cm.date
FROM chat_messages cm
INNER JOIN members m ON m.id =cm.userid
INNER JOIN chat_settings cs ON cs.id = cm.room_id
WHERE cm.setting_id = ?
ORDER BY cm.date DESC LIMIT 30 ) ddd
ORDER BY date ASC ");
$mess->bind_param("i", $room);
$mess->execute();
$mess->store_result();
$mess->bind_result($chatid,$chat_userid,$message,$voteup,$votedown,$date);
while($row = $mess->fetch()){
//im fetching here in my <div class='div1' >
}
Then, in the second div I have to add an AND condition:
$mess2 = $mysqli->prepare("SELECT * from ( SELECT cm.id ,cm.userid,cm.message,cm.voteup,cm.votedown,cm.date
FROM chat_messages cm
INNER JOIN members m ON m.id =cm.userid
INNER JOIN chat_settings cs ON cs.id = cm.room_id
WHERE cm.setting_id = ? AND voteup - votedown >= 5
ORDER BY cm.date DESC LIMIT 30 ) ddd
ORDER BY date ASC ");
$mess2->bind_param("i", $room);
$mess2->execute();
$mess2->store_result();
$mess2->bind_result($chatid,$chat_userid,$message,$voteup,$votedown,$date);
while($row2 = $mess2->fetch()){
//im fetching here in my <div class='div2' >
}
Lastly, in the third div I have a slightly different AND condition:
$mess3 = $mysqli->prepare("SELECT * from ( SELECT cm.id ,cm.userid,cm.message,cm.voteup,cm.votedown,cm.date
FROM chat_messages cm
INNER JOIN members m ON m.id =cm.userid
INNER JOIN chat_settings cs ON cs.id = cm.room_id
WHERE cm.setting_id = ? AND votedown - voteup >= 5
ORDER BY cm.date DESC LIMIT 30 ) ddd
ORDER BY date ASC ");
$mess3->bind_param("i", $room);
$mess3->execute();
$mess3->store_result();
$mess3->bind_result($chatid,$chat_userid,$message,$voteup,$votedown,$date);
while($row3 = $mess3->fetch()){
//im fetching here in my <div class='div3' >
}
Everything works BUT doing this near-same query seems clumsy. Is it possible to construct the same thing with only one query? I have used $mess->data_seek(0); but its not helping because I didn't add my condition to the query.
Just go for PhP to filter your data instead of triple query your database. In this case you can figure out to go for this solution because you call 3 times your query with the same parameter :
$mess3 = $mysqli->prepare(" SELECT *
FROM ( SELECT cm.id ,
cm.userid,
cm.message,
cm.voteup,
cm.votedown,
cm.date
FROM chat_messages cm
INNER JOIN members m ON m.id =cm.userid
INNER JOIN chat_settings cs ON cs.id = cm.room_id
WHERE cm.setting_id = ?
AND votedown - voteup >= 5
ORDER BY cm.date DESC LIMIT 30 ) ddd
ORDER BY date ASC ");
$mess3->bind_param("i", $room);
$mess3->execute();
$mess3->store_result();
$mess3->bind_result($chatid,$chat_userid ,$message,$voteup,$votedown ,$date);
while($row = $mess3->fetch()){
$voteup = $row['voteup'];
$votedown = $row['votedown'];
addToDiv1($row);
if( $voteup - $votedown >= 5 ) {
addToDiv2($row);
}
if( $votedown - $voteup >= 5 ) {
addToDiv3($row);
}
}
I will just give an answer based specifically on cleaning up your code. Technically you will still make the 3 calls in this scenario, but it will be cleaner because you include one function only, you don't see the script behind it.
As I mentioned, I am not an SQL aficionado so I can not give a good solution there (maybe you can use GROUP BY and perhaps an OR clause...I don't really know...). If I were to do this, I would do a function that can return all the options:
/core/functions/getChatMessages.php
function getChatMessages($settings,$mysqli)
{
$id = (!empty($settings['id']))? $settings['id'] : false;
$type = (!empty($settings['type']))? $settings['type'] : false;
$max = (!empty($settings['max']))? $settings['max'] : 30;
$mod = '';
// No id, just stop
if(!is_numeric($id))
return false;
// equation one
if($type == 'up')
$mod = ' AND voteup - votedown >= 5';
// equation two
elseif($type == 'down')
$mod = ' AND votedown - voteup >= 5';
$mess = $mysqli->prepare("SELECT * from ( SELECT cm.id ,cm.userid,cm.message,cm.voteup,cm.votedown,cm.date
FROM chat_messages cm
INNER JOIN members m ON m.id =cm.userid
INNER JOIN chat_settings cs ON cs.id = cm.room_id
WHERE cm.setting_id = ? {$mod}
ORDER BY cm.date DESC LIMIT {$max} ) ddd
ORDER BY date ASC");
$mess->bind_param("i", $id);
$mess->execute();
$mess->store_result();
$mess->bind_result($chatid, $chat_userid, $message, $voteup, $votedown, $date);
while($mess->fetch()){
$result[] = array(
'chatid'=>$chatid,
'chat_userid'=>$chat_userid,
'message'=>$message,
'voteup'=>$voteup,
'votedown'=>$votedown
);
}
// Send back the data
return (!empty($result))? $result : array();
}
To use:
// Include our handy function
require_once('/core/functions/getChatMessages.php');
// Store our id for use
$settings['id'] = 100;
// Should get 30 from first select
$voteGen = getChatMessages($settings,$mysqli);
// Should get 30 from second select
$settings['type'] = 'up';
$voteUp = getChatMessages($settings,$mysqli);
// Should get 15 from third select
// Just for the heck of it, I added in a limit settings
$settings['max'] = 15;
$settings['type'] = 'down';
$voteDown = getChatMessages($settings,$mysqli);
Now that you have these stored, just use a foreach loop to place them into your view. The good side of this is that you can call this where ever and when ever since the function only returns data. It allows you to work with the data in a view or non-view situation. Side note, I use PDO, so if there is something ineffective with the way the mysqli is fetching, that will be why. It's probably just best to fetch an assoc array to return...
I have two tables, users and clients_closed_1.
I need to order the result by the count of the rows on the table client_closed_1 where meeting=1.
I did it for time_closed field but that was easy because there was no condition.
It's a part of a search code so I'll show you all of it.
With this code I manage to order it by meeting - but users who has no rows with meeting=1 isn't pull out from the database and I need them to show even if they doesn't have meetings.
if (project_type($_GET['project']) == 1) {
$table = 'clients_closed_1';
} else {
$table = 'clients_closed_2';
}
$s_query = "SELECT *,COUNT(time_closed) as numc FROM `".$table."` FULL JOIN `users` ON users.ID=user_c WHERE 1=1";
if (isset($_POST['search'])) {
if ($_POST['tm'] == 'da') {
$dd = strtotime($_POST['y']."-".$_POST['m']."-".$_POST['d']);
$s_query = $s_query." && DATE(FROM_UNIXTIME(time_closed)) = DATE(FROM_UNIXTIME(".$dd."))";
}
elseif ($_POST['tm'] == 'mon') {
$s_query = $s_query." && YEAR(FROM_UNIXTIME(time_closed))=".$_POST['y']." && MONTH(FROM_UNIXTIME(time_closed))=".$_POST['m'];
}
if (!empty($_POST['search_name'])) {
$s_query = $s_query." && CONCAT(p_name,' ',l_name) LIKE '%".$_POST['search_name']."%'";
}
if (!empty($_POST['level'])) {
$query = "&& (level=3 && project IN (SELECT `project` FROM `project` WHERE type='2')) || level=4";
}
} else {
$s_query = $s_query." && YEAR(FROM_UNIXTIME(time_closed))=YEAR(NOW()) && MONTH(FROM_UNIXTIME(time_closed))=MONTH(NOW())";
}
if (isset($_GET['order'])) {
if ($_GET['order'] == 'closing') {
$s_query = $s_query." GROUP BY users.ID ORDER BY numc DESC";
}
elseif ($_GET['order'] == 'meeting') {
$s_query = $s_query." && meeting='1' GROUP BY users.ID ORDER BY numd DESC";
}
}
$query = $db->query($s_query);
If you need any more code/doedn't understand something comment please and I'll fix it.
Thank you.
EDIT:
example of $s_query:
SELECT *,COUNT(time_closed) as numc, COUNT(meeting) as numd FROM `clients_closed_1`
FULL JOIN `users` ON users.ID=user_c WHERE 1=1 &&
YEAR(FROM_UNIXTIME(time_closed))=YEAR(NOW()) &&
MONTH(FROM_UNIXTIME(time_closed))=MONTH(NOW())
GROUP BY users.ID ORDER BY numc DESC
Im not sure I understand 100% of the criteria youre looking for but here is a rough draft of the query:
SELECT c.id, c.meeting, temp1.time_closed_count, temp2.meeting_count, temp3.status_count
FROM `clients_closed_1` c
FULL JOIN `users` u
ON c.user_c=u.ID
LEFT JOIN (SELECT time_closed, count(time_closed) time_closed_count FROM clients_closed_1 GROUP BY time_closed) temp1
ON c.time_closed = temp1.time_closed
LEFT JOIN (SELECT meeting, count(meeting) meeting_count FROM clients_closed_1 GROUP BY meeting) temp2
ON c.meeting = temp2.meeting
LEFT JOIN (SELECT status, count(status) status_count FROM clients_closed_1 GROUP BY status) temp3
ON c.status = temp3.status
WHERE 1=1
AND YEAR(FROM_UNIXTIME(time_closed))=YEAR(NOW())
AND MONTH(FROM_UNIXTIME(time_closed))=MONTH(NOW())
ORDER BY {$order_criteria} DESC
Whats happeneing here is, we are doing the count of all distinct meeting values in a subquery and joining it to the original query based on the value of "meeting" for each row.
This gives us the total "meetings" grouped by distinct meeting values, without cutting out rows. Such is the same for the other 2 subqueries.
This also cleans things up a bit and allows us to just insert the $order_criteria, where that could be time_closed count, meeting_count, or status_count. Just set a default (id) in case your user does not choose anything :)
Edit: Id also recommend trying to get out of the SELECT * habit. Specify the columns you need and your output will be much nicer. Its also far more efficient when you start dealing with larger tables.
After I wrote a really long query to do this I found the perfect soulution.
SELECT SUM(IF(meeting='1' && user_c=users.ID, 1,0)) as meeting_count FROM clients_closed_1 JOIN users
This query return as meeting_count the number of meeting which their value is '1'.
I didn't know I can do such thing until now, so I shared it here. I guess it can be helpull in the future.
I have the following problem: here is the structure of my tables
and here is my code:
$SQL_NEXT_PROJECT_ID ="SELECT id FROM projects WHERE id < '".$id_project."' and project_types_id='".$project_type_id."' ORDER BY id DESC LIMIT 1";
$conn->query($SQL_NEXT_PROJECT_ID);
foreach ($conn->query($SQL_NEXT_PROJECT_ID) as $rowProjectNext) {
$next_project_id = $rowProjectNext['id'];
}
$SQL_PREVIOUS_PROJECT_ID ="SELECT id FROM projects WHERE id > '".$id_project."' and project_types_id='".$project_type_id."' ORDER BY id ASC LIMIT 1";
$conn->query($SQL_PREVIOUS_PROJECT_ID);
foreach ($conn->query($SQL_PREVIOUS_PROJECT_ID) as $rowProjectPrevious) {
$previous_project_id = $rowProjectPrevious['id'];
}
the thing is that i need to put the query with an aditional condition from the 'images' table i have to evaluate the main field ='1', i have been trying to do it with a inner join but it doesnt seem to work, here i attach the query that i have been trying
$SQL_NEXT_PROJECT_ID ="SELECT projects.id FROM projects INNER JOIN images WHERE projects.id > '".$id_project."' and project_types_id='1' and main='1' ORDER BY projects.id DESC LIMIT 1";
Basically what i need to do is to create next / previous links to projects of certain type (project_types_id) based on the current id of the project ($id_project) taking into consideration the fact that the project should have a image that has the main field equal to '1'
hope i explained myself well...
Well youre not joining on anything... you need an ON clause.
SELECT pr.id FROM projects pr
INNER JOIN images img ON (pr.id = img.projects_id AND img.main = 1)
WHERE pr.id > ?
AND pr.project_types_id = 1
ORDER BY pr.id DESC LIMIT 1
at the end i did it like this
$_nextPrevious = array();
$SQL_SEARCH_VALUES="SELECT images.projects_id AS projectId FROM projects INNER JOIN images ON ( projects.id = images.projects_id ) AND project_types_id = '".$project_type_id."' AND images.main = '1' LIMIT 0 , 30";
$conn->query($SQL_SEARCH_VALUES);
foreach($conn->query($SQL_SEARCH_VALUES) as $rowNextPrevious) {
$value = $rowNextPrevious['projectId'];
array_push($_nextPrevious, $value);
}
$currentValue = array_search($id_project, $_nextPrevious);
$next = $currentValue + 1;
$previous = $currentValue - 1;
$next_project_id = $_nextPrevious[$next];
$previous_project_id = $_nextPrevious[$previous];
return array($project_name,$project_description,$project_path, $_images, $next_project_id, $previous_project_id);
using an array instead of two searches...
I have to output some products from table 'products', along with the lowest price from the table 'product_licenses', which is the only column I need from that table in this query.
However, when I try to use the sql function MIN(), my loop only runs through the code once and gets the first result and then it stops, so I am a bit lost here.
This is the query using min() :
$mysql->query("
SELECT pd.*, min(lc.price) AS price
FROM `products` AS pd, product_licenses AS lc
WHERE pd.`status` = '1' AND lc.product_id = pd.id
ORDER BY pd.`id` ASC
$limitQuery
");
I'm using this function to get the products, but this, unfortunately, fetches the highest price:
public function getAllProducts($start = 0, $limit = 0, $order = '`datetime` ASC') {
global $mysql;
$limitQuery = '';
if ($limit != 0) {
$limitQuery = " LIMIT $start,$limit ";
}
**// Not working if I use min() on lc.price**
$mysql->query("
SELECT pd.*, lc.price
FROM `products` AS pd, product_licenses AS lc
WHERE pd.`status` = '1' AND lc.product_id = pd.id
ORDER BY pd.`id` ASC
$limitQuery
");
if ($mysql->num_rows() == 0) {
return false;
}
$this->usersWhere = '';
$return = array();
while ($d = $mysql->fetch_array()) {
$categories = explode(',', $d['category_id']);
unset($d['category_id']);
foreach ($categories as $c) {
$c = trim($c);
if ($c != '') {
$d['category_id'][$c] = $c;
}
}
$return[$d['id']] = $d;
}
$this->foundRows = $mysql->getFoundRows();
return $return;
}
Add GROUP BY in your query. your current query returns only one result since your are using aggregate function (MIN) but not grouping it.
SELECT pd.col1,
pd.col2, min(lc.price) AS PRICE
FROM `products` AS pd
INNER JOIN product_licenses AS lc
ON lc.product_id = pd.id
WHERE pd.`status` = '1'
GROUP BY pd.col1, pd.col2, pd.col3
ORDER BY pd.`id` ASC
$limitQuery
PS: post the structure of your database with records. It will the community understands your question clearly :)
You have no group by clause in your query, so the query is returning the first row only.
SELECT pd.col1, pd.col2, pd.col3, min(lc.price) AS price
FROM `products` AS pd, product_licenses AS lc
WHERE pd.`status` = '1' AND lc.product_id = pd.id
group by pd.col1, pd.col2, pd.col3
ORDER BY pd.`id` ASC
$limitQuery
You'll need a GROUP BY in there, like so:
SELECT pd.*, min(lc.price) AS price
FROM `products` AS pd, product_licenses AS lc
WHERE pd.`status` = '1' AND lc.product_id = pd.id
GROUP BY pd.`id`
ORDER BY pd.`id` ASC
$limitQuery
Note that with MySQL, you only need to group by the id column even though you are selecting other columns from the products table.
For example I have a mysql query that gets some data. Then runs another query based some of the data that it got.
If i just return the first query, in my case $qOne. Everything works great.
BUT, after using my while loop while ($row = mysql_fetch_array($qOne)) It then returns as an empty array. (but the second query I return DOES work)
I tried to see if I could "save" the first query in another var im not messing with like this $savedResult = $qOne, then i'd just return the $savedResult but that did not work.
Does anyone know how I can get my function below to return both of the results? Thanks!
function getFoods($sort, $start, $limit) {
$qOne = mysql_query("SELECT a.id, a.name, a.type, AVG(b.r) AS fra, COUNT(b.id) as tvotes FROM `foods` a LEFT JOIN `foods_ratings` b ON a.id = b.id GROUP BY a.id ORDER BY fra DESC, tvotes DESC LIMIT $start, $limit;");
$i = 0;
$qry = "";
while ($row = mysql_fetch_array($qOne)) {
$fid = $row['id'];
if ($i > 0)
$qry .= " UNION ";
$i++;
$qry .= "SELECT fid, ing, amount FROM foods_ing WHERE fid='$fid'";
}
$qTwo = mysql_query($qry);
return array($qOne, $qTwo);
}
When you have returned the two query result resources, remember that you will need to fetch from them when you actually want to use them. (we don't see the code where you implement that).
To make use of $qOne after you already have looped through it, you must rewind it back to the first position. That is done with mysql_data_seek()
mysql_data_seek($qOne, 0);