I have code like this:
function search_keyword(){
$keyword = trim($_POST['keyword']);
$search_explode = explode(" ", $keyword);
$x = 0;
$sql = " ( SELECT name AS type FROM global_info WHERE ";
foreach($search_explode as $each){
$x++;
if($x == 1){
$sql .= " name LIKE '%$each%'";}
else {
$sql .= " name LIKE '%$each%' ";
}
}
$sql .= " ) UNION ALL ";
$sql .= " ( SELECT name AS type FROM person WHERE ";
foreach($search_explode as $each){
$x++;
if($x == 1){
$sql .= " name LIKE '%$each%'";}
else {
$sql .= " name LIKE '%$each%' ";
}
}
$sql .= " ) UNION ALL ";
$sql .= "( SELECT name AS type FROM event WHERE ";
foreach($search_explode as $each){
$x++;
if($x == 1){
$sql .= " name LIKE '%$each%'";}
else {
$sql .= " name LIKE '%$each%' ";
}
}
$sql .= " ) ";
$q = $this->db->query($sql);
return $q = $q->num_rows() == 0 ? FALSE : $q->result();
}
The function is working. What I don't know is how to know which data is from which table, and then to show the results on the page?
Perhaps, adding a field to the results of each SELECT.
function search_keyword(){
$keyword = trim($_POST['keyword']);
$search_explode = explode(" ", $keyword);
$x = 0;
$sql = " ( SELECT name AS type, \"table_global_info\" as mytable FROM global_info WHERE ";
foreach($search_explode as $each){
$x++;
if($x == 1){
$sql .= " name LIKE '%$each%'";}
else {
$sql .= " name LIKE '%$each%' ";
}
}
$sql .= " ) UNION ALL ";
$sql .= " ( SELECT name AS type, \"person\" as mytable FROM person WHERE ";
foreach($search_explode as $each){
$x++;
if($x == 1){
$sql .= " name LIKE '%$each%'";}
else {
$sql .= " name LIKE '%$each%' ";
}
}
$sql .= " ) UNION ALL ";
$sql .= "( SELECT name AS type, \"event\" as mytable FROM event WHERE ";
foreach($search_explode as $each){
$x++;
if($x == 1){
$sql .= " name LIKE '%$each%'";}
else {
$sql .= " name LIKE '%$each%' ";
}
}
$sql .= " ) ";
$q = $this->db->query($sql);
return $q = $q->num_rows() == 0 ? FALSE : $q->result();
}
Regards!
In select statement insert anew column that identifies the table:
SELECT name AS type, 'tab_x' as from_table FROM global_info WHERE
....
SELECT name AS type, 'tab_x1' as from_table FROM global_info WHERE
when you use the returned values check the "from_table" field to see the orginal table the result come from
Related
I am trying to build search logic that uses multiple form fields and adjusts the MySQL search accordingly. My main area of issue is when dealing with multiple checkboxes. The below gets me close but I get multiple "OR" at the end for some reason. The below gives me (nema = '1' OR OR nema = '12' OR OR nema = '4' OR OR ) for example. More OR's are added for each checkbox. What am I missing or not doing correctly?
$rating = mysqli_real_escape_string($db, implode(',', $_POST['rating']));
$q = "SELECT * FROM lekker WHERE height BETWEEN 20 AND 30 ";
if (!empty($rating)) {
$var = explode(',',$rating);
$rating_count = count($var);
if($rating_count > 1) {
$q .= "AND (";
foreach($var as $test) {
$q .= "nema = '$test'";
for($i=0;$i<$rating_count;$i++) {
if($i!=$rating_count-1) {
$q .= " OR ";
}
}
}
$q .= " )";
} else {
$q .= "nema = '$rating'";
}
}
$q .= " ORDER BY `part` ASC";
This is the Select I am trying to achieve:
SELECT * FROM lekker WHERE height BETWEEN 20 AND 22 AND (nema = '1' OR nema = '12') ORDER BY part ASC
I removed the second loop and always add OR, then you can remove the last one at the end
$rating = mysqli_real_escape_string($db, implode(',', $_POST['rating']));
$q = "SELECT * FROM lekker WHERE height BETWEEN 20 AND 30 ";
if (!empty($rating)) {
$var = explode(',',$rating);
$rating_count = count($var);
if($rating_count > 1) {
$q .= "AND (";
foreach($var as $test) {
$q .= "nema = '$test' OR ";
}
$q=substr($q, 0,-4);
$q .= " )";
} else {
$q .= "nema = '$rating'";
}
}
$q .= " ORDER BY `part` ASC";
Instead of worrying about whether or not you need to add an OR simply add it each time through your foreach then trim off the trailing OR after you are done with the foreach.
if ($rating_count > 1) {
$q .= "AND (";
foreach($var as $test) {
$q .= "nema = '$test' OR ";
}
$q .= rtrim($q,' OR ') . ' )';
} else {
$q .= "nema = '$rating'";
}
Currently I'm developing a search form so my SQL query needs to change with user input. Please see the below code sample.
$sqlSearch = "SELECT * FROM seafarers WHERE ";
if ($dateS != "") {
$sqlSearch .= "add_date = '" . changeDateSlashToHypen($dateS) . "' and ";
}
if ($cdcS != "") {
$sqlSearch .= "cdc = '" . $cdcS . "' and ";
}
if ($ppS != "") {
$sqlSearch .= "passport LIKE '%$ppS%' and ";
}
if ($surnameS != "") {
$sqlSearch .= "surname LIKE '" . $surnameS . "%' and ";
In order to execute this statement the user must select all the options; the statement will not work if the user selects one or two options.
Don't patch your query together like this. Use Prepared Statements. Example:
SELECT *
FROM seafarers
WHERE (:dt is null or add_date = :dt)
and (:cdc is null or cdc = :cdc)
You have to fill the parameters of the query before execution.
Start out with a placeholder like 1=1 which will always be true, and then use AND as a prefix instead of a suffix.
$sqlSearch = "SELECT * FROM seafarers WHERE 1=1 ";
if ($dateS != "") {
$sqlSearch .= " AND add_date = '" . changeDateSlashToHypen($dateS) . "'";
}
...
But as pointed out in the other answer you need to use prepared statements. So, assuming you're using mysqli, which everyone seems to do for some reason:
$sqlSearch = "SELECT * FROM seafarers WHERE 1=1 ";
$types = "";
$parameters = [];
if ($dateS != "") {
$sqlSearch .= " AND add_date = ?";
$types .= "s";
$parameters[] = changeDateSlashToHypen($dateS);
}
if ($cdcS != "") {
$sqlSearch .= " AND cdc = ?";
$types .= "s";
$parameters[] = $cdcS;
}
if ($ppS != "") {
$sqlSearch .= " AND passport LIKE ?";
$types .= "s";
$parameters[] = "%$ppS%";
}
if ($surnameS != "") {
$sqlSearch .= " AND surname LIKE ?";
$types .= "s";
$parameters[] = "$surnameS%";
}
$stmt = $db->prepare($sqlSearch);
if (count($parameters) {
$stmt->bind_param($types, ...$parameters);
}
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
...
}
I am trying to create a search field where people can search with tags that are saved in our database (ajax). The problem is that I want the user to be able to search with tags for content, where the content MUST have tags attached that include all the tags that were used for the search. So let's say I search for 'bwm red', I want to only show content with both the tags 'bmw' and 'red' attached to it. So NO content with only one of the two tags.
Additionally, the user can search for tags that are optional, so let's say the user searches for 'red yellow', the results should be content either with tags 'red' or 'yellow', where it also matches with the MUST search field. By doing so you get a very specific search.
In the photo here I have included the design how the search field should work, and it should be more clear what I am trying to create.
I have also written some code, but as you can see it is not working how I want to be.
Any idea how I can solve this problem?
<form action="search.php" method="post" >
<h2>Search Keywords:</h2>
<h3>MUST</h3>
<input type="text" name="must">
<h3>Optional</h3>
<input type="text" name="keyword">
<input type="submit" value="Search">
</form>
if(!empty($_POST))
{
$aMust = explode(" ", $_POST['must']);
$aKeyword = explode(" ", $_POST['keyword']);
$query ="SELECT * FROM table1 WHERE field1 like '%" . $aKeyword[0] . "%'";
for($i = 1; $i < count($aKeyword); $i++) {
if(!empty($aKeyword[$i])) {
$query .= " OR field1 like '%" . $aKeyword[$i] . "%'";
}
}
$result = $db->query($query);
echo "<br>You have searched for keywords: " . $_POST['keyword'];
if(mysqli_num_rows($result) > 0) {
$row_count=0;
echo "<br>Result Found: ";
echo "<br><table border='1'>";
While($row = $result->fetch_assoc()) {
$row_count++;
echo "<tr><td> ROW ".$row_count." </td><td>". $row['field1'] . "</td></tr>";
}
echo "</table>";
}
else {
echo "<br>Result Found: NONE";
}
}
You need to use UNION to get the records and show data like below
$aMust = explode(" ", $_POST['must']);
$aKeyword = explode(" ", $_POST['keyword']);
$query ="SELECT * FROM table1 WHERE (";
for($i = 0; $i < count($aMust); $i++) {
if( $i!=0 && $i != (count($aMust)-1) ) {
$query .=" AND ";
}
if(!empty($aMust[$i])) {
$query .=" field1 like '%" . $aMust[$i] . "%' ";
}
}
$query .=" ) ";
if( count($aKeyword) > 0 ) {
$query .= " AND (";
for($i = 0; $i < count($aKeyword); $i++) {
if( $i!=0 && $i != (count($aKeyword)-1) ) {
$query .=" OR ";
}
if(!empty($aKeyword[$i])) {
$query .= " field1 like '%" . $aKeyword[$i] . "%'";
}
}
$query .= " ) ";
}
$query .=" UNION ";
$query .=" SELECT * FROM table1 WHERE (";
for($i = 0; $i < count($aMust); $i++) {
if( $i!=0 && $i != (count($aMust)-1) ) {
$query .=" AND ";
}
if(!empty($aMust[$i])) {
$query .=" field1 like '%" . $aMust[$i] . "%' ";
}
}
$query .=" ) ";
This will give you those records which matches the optional values and which do not matches the optional values but matches the must values.
UNION do not gives duplicate records, so you don't have to worry for duplicate values coming.
In case any issue, let me know in comments.
Unlike How do I perform an IF…THEN in an SQL SELECT?
, I'm asking about a PHP variable.
I'm trying to create a SQL SELECT statement on my PHP file which can select all person or single person.
if ( $watch_person == "all") {
$sql = "SELECT WORK_RECORD
FROM worklist
";
} else {
$sql = "SELECT WORK_RECORD
FROM worklist
WHERE PERSON_NO = '".$watch_person."'
";
}
Is there a way to do this in one SQL statement?
Here's how I would do it:
$sql = "SELECT WORK_RECORD FROM worklist";
if($watch_person != "all"){
$sql .= " WHERE PERSON_NO = '$watch_person'";
}
You can optimize your coding as below.
$sql = "SELECT WORK_RECORD
FROM worklist WHERE ";
if ( $watch_person == "all") {
$sql .= " 1=1";
} else {
$sql .= " PERSON_NO = '".$watch_person."' ";
}
OR
$sql = "SELECT WORK_RECORD
FROM worklist WHERE ". ($watch_person == "all" ? "1=1" : "PERSON_NO = '".$watch_person."'");
you can have the where statement in the if else.
$sql = "SELECT WORK_RECORD
FROM worklist ".
($watch_person == "all" ? "" : "WHERE PERSON_NO = '".$watch_person."'");
It will be more easy to extend where condition.
.
$sql = "SELECT WORK_RECORD
FROM worklist WHERE 1=1 ";
if ( $watch_person != "all")
$sql .= " and PERSON_NO = '".$watch_person."' ";
if ( $watch_person2 != "another")
$sql .= " and example = '".$watch_person2."' ";
I'm trying to do a search based on
<select multiple=multiple name="chkUnr[]">
I'm getting out the values from select by running code:
for($i=0;$i<count($_POST["chkUnr"]);$i++)
{
if($_POST["chkUnr"][$i] != "")
{
$search_country = $_POST["chkUnr"][$i];
}
$query = "";
$query .= "SELECT users.* FROM users";
if (isset($_POST['singles_online']) ? $_POST['singles_online'] : 0 == 1) {
$query .= " LEFT JOIN online ON online.user_id = users.id";
}
$query .= " WHERE";
if (isset($_POST['vip']) ? $_POST['vip'] : 0 == 1) {
$query .= " users.vip = 1 AND";
}
if (isset($_POST['profile_image']) ? $_POST['profile_image'] : 0 == 2) {
$query .= " users.profile_image = '2' AND";
}
if (isset($_POST['singles_online']) ? $_POST['singles_online'] : 0 == 1) {
$query .= " online.is_online = 1 AND";
}
$query .= " (id NOT IN (SELECT user_id FROM users_blocked WHERE blocked_id = '$user_id')) AND";
$query .= " (users.user_age >= '$age_from' AND users.user_age <= '$age_to') AND";
$query .= " (users.gender = '$gender_search') AND";
$query .= " users.country IN ('$search_country')";
$search_query = mysql_query($query);
}
And i can print out the values but the problem comes when i do the SQL search.
It only pick up the first value in this case im using countries:
So when i select Sweden, Germany, Usa i can print them all out but when trying to do a SQL query only Sweden is being picked up.
I've tried with this code but still same result.
The problem here (and with the other answer) is that the in clause was surrounded by quotes, so that will not yield the result that we want. We need to effectively pass in an array to the query. Also your code is vulnerable to sql injection. I would strongly suggest moving to PDO/prepared statements. I added a slight protection to the countries, but that is not foolproof by any means.
function prepareForSql($value, $key) {
return addslashes($value);
}
array_walk($_POST["chkUnr"], "prepareForSql");
$search_country = "'" . implode("','", $_POST["chkUnr"]) . "'";
$query = "";
$query .= "SELECT users.* FROM users";
if (isset($_POST['singles_online']) ? $_POST['singles_online'] : 0 == 1) {
$query .= " LEFT JOIN online ON online.user_id = users.id";
}
$query .= " WHERE";
if (isset($_POST['vip']) ? $_POST['vip'] : 0 == 1) {
$query .= " users.vip = 1 AND";
}
if (isset($_POST['profile_image']) ? $_POST['profile_image'] : 0 == 2) {
$query .= " users.profile_image = '2' AND";
}
if (isset($_POST['singles_online']) ? $_POST['singles_online'] : 0 == 1) {
$query .= " online.is_online = 1 AND";
}
$query .= " (id NOT IN (SELECT user_id FROM users_blocked WHERE blocked_id = '$user_id')) AND";
$query .= " (users.user_age >= '$age_from' AND users.user_age <= '$age_to') AND";
$query .= " (users.gender = '$gender_search') AND";
$query .= " users.country IN ($search_country)";
$search_query = mysql_query($query);
Try
$search_country = implode(',',array_unique($_POST["chkUnr"]));
$query = "";
$query .= "SELECT users.* FROM users";
if (isset($_POST['singles_online']) ? $_POST['singles_online'] : 0 == 1) {
$query .= " LEFT JOIN online ON online.user_id = users.id";
}
$query .= " WHERE";
if (isset($_POST['vip']) ? $_POST['vip'] : 0 == 1) {
$query .= " users.vip = 1 AND";
}
if (isset($_POST['profile_image']) ? $_POST['profile_image'] : 0 == 2) {
$query .= " users.profile_image = '2' AND";
}
if (isset($_POST['singles_online']) ? $_POST['singles_online'] : 0 == 1) {
$query .= " online.is_online = 1 AND";
}
$query .= " (id NOT IN (SELECT user_id FROM users_blocked WHERE blocked_id = '$user_id')) AND";
$query .= " (users.user_age >= '$age_from' AND users.user_age <= '$age_to') AND";
$query .= " (users.gender = '$gender_search') AND";
$query .= " users.country IN ('$search_country')";
$search_query = mysql_query($query);