Mysql query with multiple ands and ors - php

I'm trying to make a filter function for servers on my site. Users are able to check different options for the categories they want to filter for, and I have an ajax request that returns the servers satisfying their conditions. However, my mysql_query isn't working, I think I might have the wrong syntax.
By default, each category has the option set as 1. My current query is:
$order = "SELECT * FROM `servers`
WHERE `size` = '$size' or
1 = '$size' and
`type` = '$type' or
1 = '$type' and
`mode` = '$gamemode' or
1 = '$gamemode' and
`main` = '$main' or
1 = '$main'
ORDER BY $orderby
LIMIT 5";
It doesn't seem to get the correct servers, do I have an error in my query?
Thanks!

When mixing and and or in your query you must use parenthesis to group the conditions. Also, I think when you say 1 = '$size', I think you mean `size`=1.
$order = "SELECT * FROM `servers`
WHERE
(`size` = '$size' or `size` = '1') and
(`type` = '$type' or `type` = 1) and
(`mode` = '$gamemode' or `mode`= 1 ) and
(`main` = '$main' or `main` = 1)
ORDER BY $orderby
LIMIT 5";

"SELECT * FROM `servers` WHERE
`size` in ('$size', 1) and
`type` in( '$type' ,1) and
`mode` in('$gamemode' ,1) and
`main` in ( '$main' , 1 )
ORDER BY $orderby LIMIT 5";

You need to add parentheses because or and and have a different order of operations and needs parentheses to allow what you are needing to accomplish
SELECT * FROM `servers` WHERE
(`size` = '$size' or 1 = '$size') and
(`type` = '$type' or 1 = '$type') and
(`mode` = '$gamemode' or 1 = '$gamemode') and
(`main` = '$main' or 1 = '$main')
ORDER BY $orderby LIMIT 5

you must have to use brackets to use multiple OR condition in query
like
mysql_query("SELECT * FROM servers WHERE email='$Email' AND (date='$Date_Today' OR date='$Date_Yesterday' OR date='$Date_TwoDaysAgo' OR date='$Date_ThreeDaysAgo' OR date='$Date_FourDaysAgo')");
you can change with your column name
and also you can use IN condtion like
mysql_query("SELECT * FROM servers WHERE email='$Email' AND date IN ('$Date_Today','$Date_Yesterday','$Date_TwoDaysAgo')");
pls let me know if i can help you more

Just try to put brace around the or conditions
$order = "SELECT * FROM `servers` WHERE (`size` = '$size' or 1 = '$size') and (`type` = '$type' or 1 = '$type') and (`mode` = '$gamemode' or 1 = '$gamemode') and (`main` = '$main' or 1 = '$main') ORDER BY '$orderby' LIMIT 5";

Related

Return results from multiple table fields

I've got returns results from a query but I would like it to return multiple results, this is the current query:
$qry = "SELECT * FROM properties WHERE isLeased = 0 AND featured = 1 ORDER BY RAND() LIMIT 9";
$res = mysqli_query($mysqli, $qry) or die('-1' . mysqli_error());
What I would like is for it to return those results, as well as the results for:
$qry = "SELECT * FROM properties WHERE isLeased = 0 AND propertyType = 'For Sale' ORDER BY RAND() LIMIT 3";
$res = mysqli_query($mysqli, $qry) or die('-1' . mysqli_error());
But if I just add the second section of code below the first one it only returns the results of the first one.
How could I tell it to return results based on a couple of tables?
You can use a UNION query:
SELECT t1.*
FROM
(
SELECT *
FROM properties
WHERE isLeased = 0 AND featured = 1
ORDER BY RAND()
LIMIT 9
) t1
UNION ALL
SELECT t2.*
FROM
(
SELECT *
FROM properties
WHERE isLeased = 0 AND propertyType = 'For Sale'
ORDER BY RAND()
LIMIT 3
) t2

Limited number of SQL Query selectors

I can't figure out what is wrong with my query. I have three elements that control the order of posts: quartier, block and number. And it is working well.
I want to add a fourth named street. When I do so, nothing is fetched. I thought maybe there is a problem with street, but if for example I leave street but remove block, it is working again and uses street appropriately.
My conclusion is that the database only accepts a limited number of selectors per query. Is that true? Or am I missing something?
$query = "SELECT `wp_posts`.`post_title` , `wp_posts`.`ID` , `end`.`meta_value` AS `enddate` , `start`.`meta_value` as `startdate`, `quartier`.`meta_value` AS `thequartier`, `street`.`meta_value` AS `thestreet`, `number`.`meta_value` AS `thenumber`, `block`.`meta_value` AS `theblock`
FROM `wp_posts` , `wp_postmeta` AS `end` , `wp_postmeta` AS `start` , `wp_postmeta` AS `quartier`, `wp_postmeta` AS `street`, `wp_postmeta` AS `number`, `wp_postmeta` AS `block`
WHERE `wp_posts`.`post_type` = 'listing'
AND `wp_posts`.`ID` = `end`.`post_id`
AND `wp_posts`.`ID` = `start`.`post_id`
AND `wp_posts`.`ID` = `quartier`.`post_id`
AND `wp_posts`.`ID` = `street`.`post_id`
AND `wp_posts`.`ID` = `block`.`post_id`
AND `wp_posts`.`ID` = `number`.`post_id`
AND `end`.`meta_key` = 'theend'
AND `end`.`meta_value` >= '".time()."'
AND `start`.`meta_key` = 'thestart'
AND `start`.`meta_value` <= '".time()."'
AND `quartier`.`meta_key` = 'quartier'
AND `street`.`meta_key` = 'street'
AND `number`.`meta_key` = 'number'
AND `block`.`meta_key` = 'block'
AND `wp_posts`.`post_status` = 'publish'
GROUP BY `wp_posts`.`ID`
ORDER BY `thequartier` + 0 ASC";
$calendar = $wpdb->get_results($query, ARRAY_A);
foreach ($calendar as $key => $row) {
$thequartier[$key] = $row['thequartier'];
$thestreet[$key] = $row['thestreet'];
$theblock[$key] = $row['theblock'];
$thenumber[$key] = $row['thenumber'];
}
// Sort the data with volume descending, edition ascending
array_multisort($thequartier, SORT_ASC, $theblock, SORT_ASC, $thestreet, SORT_ASC, $thenumber, SORT_ASC, $calendar);
Update: I found the solution for my problem, adding the following line to allow the excessive amount of selectors:
$wpdb->query("SET SQL_BIG_SELECTS=1");

if argument inside mysql query

I have now three different PHP pages that contain almost the same information so to be able to reduce this to one page I need to have a php variable inside the mysql query.
Today it is like this:
$query1 = "SELECT * FROM `Yrker` WHERE `Kategori` = '1' AND `Bruk` = '1' ORDER BY yearstart DESC, mndstart DESC";`
I need that the " AND Bruk = '1'" is removed from this query-line if i put ?nobruk=no in the adressbar. Is this possible and if so, how?
You don't want to (and can't) put an if inside your query; you want to use an if to create your query based on some condition. There are lots of ways to write this, one of which is
if (!empty($_GET['nobruk'])) {
$query1 = "SELECT ... WHERE `Kategori` = '1' ORDER BY ...";
}
else {
$query1 = "SELECT ... WHERE `Kategori` = '1' AND `Bruk` = '1' ORDER BY ...";
}
Another way, which is shorter and involves the ternary operator, is
$includeBruk = empty($_GET['nobruk']);
$query1 = "SELECT ... WHERE `Kategori` = '1' ".
($includeBruk ? "AND `Bruk` = '1' " : "").
"ORDER BY ...";
A simple if statement:
$query1 = "SELECT * FROM `Yrker` WHERE `Kategori` = '1'";
if ($_GET['nobruk']!='no') {
$query1.=" AND `Bruk` = '1'";
}
$query1.= " ORDER BY yearstart DESC, mndstart DESC";
Like this :
<?php
$query = ($_REQUEST['nobruk'] == "no") ? "SELECT * FROM `Yrker` WHERE `Kategori` = '1' ORDER BY yearstart DESC, mndstart DESC": "SELECT * FROM `Yrker` WHERE `Kategori` = '1' AND `Bruk` = '1' ORDER BY yearstart DESC, mndstart DESC";
echo $query;
?>
$query1 = "SELECT * FROM `Yrker` WHERE `Kategori`='1' ".($_GET['nobruk'] === 'no' ? "" : "AND `Bruk`='1' ")."ORDER BY yearstart DESC, mndstart DESC";

Use result of query in a second query

I'm trying to use the result of one query as part of a WHERE in a second query. I'm not sure how to best approach this, any assistance is greatly appreciated:
First Query:
$result = mysql_query("SELECT `keyword` FROM `history` ORDER BY `last_update` ASC LIMIT 1 ");
while($row = mysql_fetch_array($result))
$keyword = $row['keyword'];
Second Query
$result = mysql_query("SELECT `id` FROM `data_store` WHERE `keyword`= [result from my first query] ORDER BY `id` DESC LIMIT 1");
while($row = mysql_fetch_array($result))
$id = $row['id'];
For clarification, keyword.data_store relates to keyword.history
Use subquery
$result = mysql_query("
SELECT `id`
FROM `data_store`
WHERE `keyword` = (SELECT `keyword`
FROM `history`
ORDER BY `last_update` ASC
LIMIT 1)
ORDER BY `id` DESC");
while($row = mysql_fetch_array($result))
$id = $row['id'];
(Stripped out PHP aspects because it is irrelevant)
SELECT `id` FROM `data_store` WHERE
`keyword` IN (
SELECT `keyword` FROM `history` ORDER BY `last_update` ASC LIMIT 1
)
ORDER BY `id` DESC LIMIT 1
$result = mysql_query("SELECT `id`
FROM `data_store`
WHERE `keyword` = (
SELECT `keyword`
FROM `history`
ORDER BY `last_update` ASC
LIMIT 1 )
ORDER BY `id` DESC LIMIT 1");

MySQL -- How to do this better?

$activeQuery = mysql_query("SELECT count(`status`) AS `active` FROM `assignments` WHERE `user` = $user_id AND `status` = 0");
$active = mysql_fetch_assoc($activeQuery);
$failedQuery = mysql_query("SELECT count(`status`) AS `failed` FROM `assignments` WHERE `user` = $user_id AND `status` = 1");
$failed = mysql_fetch_assoc($failedQuery);
$completedQuery = mysql_query("SELECT count(`status`) AS `completed` FROM `assignments` WHERE `user` = $user_id AND `status` = 2");
$completed = mysql_fetch_assoc($completedQuery);
There has to be a better way to do that, right? I don't know how much I need to elaborate as you can see what I'm trying to do, but is there any way to do all of that in one query? I need to be able to output the active, failed, and completed assignments, preferably in one query.
You can try something like this query
SELECT Status , COUNT(*) StatusCount
FROM assignments
WHERE Status IN (0, 1, 2)
AND User = $user_id
GROUP BY Status
Try this
$activeQuery = SELECT status, count(status) as "status count" FROM `assignments` WHERE `user` = $user_id GROUP BY `status`
edit: added group by
Instead of doing them individually you could use the following single SQL statement
SELECT count(*), `status`
FROM `assignments`
WHERE `user` = $user_id
AND `status` in (0,1,2)
GROUP BY `status`
ORDER BY `status`
The loop around the result set to extract the results.
SELECT
(SELECT COUNT(*) FROM `assignments` WHERE `user` = $user_id AND `status` = 0) AS active,
(SELECT COUNT(*) FROM `assignments` WHERE `user` = $user_id AND `status` = 1) AS failed,
(SELECT COUNT(*) FROM `assignments` WHERE `user` = $user_id AND `status` = 2) AS completed,
FROM `assignments`
GROUP BY active, failed, completed
Haven't checked the markup, but this is near or near enough.
Use the GROUP BY to get it in one query, but on separate rows.
$query = mysql_query("SELECT `status`, count(*) AS `num` FROM `assignments` WHERE `user` = $user_id AND `status` in (0,1,2) GROUP BY `status` ORDER BY `status` ASC");
$active_count = 0;
$failed_count = 0;
$completed_count = 0;
while ($array = mysql_fetch_assoc($query))
{
if ($array['status'] == 0)
$active_count = $array['num'];
else if ($array['status'] == 1)
$failed_count = $array['num'];
else if ($array['status'] == 2)
$completed_count = $array['num'];
}
When I have the option, I'm in the habit of using prepared statement(s) to help protect against sql-injection protection and for efficiency (requires using mysqli).
But if this is not an option, then
SELECT
CASE `status`
WHEN 0 THEN `active`
WHEN 1 THEN `failed`
WHEN 2 THEN `completed`
ELSE `unknown`
END
AS `statuslabel`,
COUNT(status)
AS `statuscount`
FROM `assignments`
WHERE `user` = $escaped_user_id
GROUP BY `statuslabel`
ORDER BY `statuslabel`
Note the use of the $escaped_user_id, which would be created beforehand:
$escaped_user_id = mysql_real_escape_string($user_id);

Categories