I've got a pretty complex SQL statement and want to add a WHERE clause that only selects results WHERE the hidden column IS NOT '1', however it needs to relate to a specific user.
i.e If in table 1 hidden is 1 and userid is 1 I don't want to get this results. However as there is no record for user 2 in that table I want them to see it.
This is what I have managed to get working so far:
$where .= " AND uh.hidden IS NULL ";
However if I login as User 2 then I see the same results as user 1.
How do I make it so results are shown based on the user too?
SQL query:
$pdo = new PDO('mysql:host=localhost;dbname=myDB', 'root', 'root');
$select = 'SELECT tl.id,
tl.name,
tl.locale,
ROUND(AVG(pr.rating),0) AS rating ';
$from = ' FROM theList AS tl ';
$join = ' LEFT JOIN post_rating AS pr ON tl.id = pr.postid ';
$join2 = ' LEFT JOIN user_hidden_list AS uh ON uh.est_id = tl.id ';
$opts = isset($_POST['filterOpts']) ? $_POST['filterOpts'] : [''];
$where = ' WHERE 1 = 1 ';
if (in_array("pub", $opts)) {
$where .= " AND pub = 1";
}
if (in_array("bar", $opts)) {
$where .= " AND bar = 1";
}
$where = ' WHERE uh.hidden IS NULL ';
$group = ' GROUP BY tl.id, tl.name ';
$sql = $select . $from . $join . $join2 . $where . $group;
$statement = $pdo->prepare($sql);
$statement->execute();
$results = $statement->fetchAll(PDO::FETCH_ASSOC);
$json = json_encode($results);
echo($json);
I have 2 tables. Table 1 is a schedule which holds weekly games. Table 2 is a separate table where you select just one team from the scheduled games for a week.
I am trying to get the difference in the score for the game that I chose a team for. So for a specific week, there are 13-16 games. I select 1 team from one of those games. If the team I pick wins, the result is the difference in the score. So if my team wins and the score is 27-10, I show 17 point. I have tried every way I can think to get this, but the best I seem to come up with is that it will calculate the last game of the week only, not the specific game that my team is involved in. The gameID is the key between both tables. Is it possible to do this? I thought by grabbing the values based on gameID from the array it would match it to the gameID associated with the selection from table 2.I am able to display the correct team, week by week, but not get the point differential for that specific game. Any ideas?
<?php
for($wk=1;$wk<=17;$wk++){
$allScoresIn = true;
$currentDT = date('Y-m-d H:i:s');
//get array of games
$games = array();
$sql = "select s.*, (DATE_ADD(NOW(), INTERVAL " . SERVER_TIMEZONE_OFFSET . " HOUR) > gameTimeEastern or DATE_ADD(NOW(), INTERVAL " . SERVER_TIMEZONE_OFFSET . " HOUR) > '" . $cutoffDateTime . "') as expired ";
$sql .= "from " . DB_PREFIX . "schedule s ";
$sql .= "where s.weekNum = " . $wk . " ";
$sql .= "order by s.gameTimeEastern, s.gameID";
$query = $mysqli->query($sql);
if ($query->num_rows > 0) {
$e = 0;
$homePtDiff = 0;
$visitorPtDiff = 0;
while ($row = $query->fetch_assoc()) {
$games[$row['gameID']]['gameID'] = $row['gameID'];
$games[$row['gameID']]['homeID'] = $row['homeID'];
$games[$row['gameID']]['visitorID'] = $row['visitorID'];
$games[$row['gameID']]['homeScore'] = $row['homeScore'];
$games[$row['gameID']]['visitorScore'] = $row['visitorScore'];
$games[$row['gameID']]['homeDiff'][$e] = $row['homeScore'] - $row['visitorScore'];
$games[$row['gameID']]['visitorDiff'][$e] = $row['visitorScore'] - $row['homeScore'];
$homePtDiff = $row['homeScore'] - $row['visitorScore'];
$visitorPtDiff = $row['visitorScore'] - $row['homeScore'];
if ((int)$row['homeScore'] != NULL && (int)$row['visitorScore'] != NULL) {
$scoreEntered = TRUE;
}else{
$scoreEntered = FALSE;
}
if ((int)$games[$row['gameID']]['homeScore'] > (int)$games[$row['gameID']]['visitorScore']) {
$games[$row['gameID']]['winnerID'] = $row['homeID'];
}else if ((int)$games[$row['gameID']]['homeScore'] < (int)$games[$row['gameID']]['visitorScore']){
$games[$row['gameID']]['winnerID'] = $row['visitorID'];
}
else{
$games[$row['gameID']]['winnerID'] = NULL;
}
$e++;
}
}
$sqlinner = "select * from " . DB_PREFIX . "pickmargin where weekNum = " . $wk . " and userID = " . $x . ";";
$queryinner = $mysqli->query($sqlinner);
if ($queryinner->num_rows > 0) {
$resultinner = $queryinner->fetch_assoc();
$currentPick = $resultinner['pickmargin'];
$currentGameID = $resultinner['gameID'];
$hidePicks = $resultinner['showPicks'];
$marginPts = 0;
$y_value = $x_value-1;
} else {
$currentPick = 'TBD';
}
if ($currentPick == $games[$row['gameID']]['homeID']){
$marginPts = (int)$games[$row['gameID']]['homeScore'] - (int)$games[$row['gameID']]['visitorScore'];
}
else{
$marginPts = (int)$games[$row['gameID']]['visitorScore'] - (int)$games[$row['gameID']]['homeScore'];
}
// ...
}
I'm making a simple search engine in PHP (with PDO) and MySQL, its goal is to find products in a stock.
My TABLE phone has a COLUMN snowden which is a TINYINT (containing 0 or 1). I want to be able to get results if phone.snowden is true and the user's input is 'snowden'.
Here's a short version of my query: (:search_0 is the user's input. This is a prepared query for PDO)
SELECT * FROM phone WHERE phone.snowden = 1 AND :search_0 = `snowden`
Of course the real query is actually longer (joining multiple tables and searching into many columns) but everything works except this.
When I try to search 'snowden' I get no result (meaning the keyword(s) have not been found in any column and the 'snowden' case doesn't work).
Do I miss something about the syntax ?
How can I achieve this query in the way I tried ?
How can I achieve this with a comparison with the column name (if this is a better way to proceed) ?
EDIT: Full code
Here's the full code I use:
$keywords = explode(" ", $_POST['query']);
$query = "SELECT phone.id, phone.imei, phone.model, phone.color, phone.capacity, phone.grade, phone.sourcing, phone.entry, phone.canal, phone.sale, phone.state, phone.snowden FROM phone LEFT JOIN capacity ON (phone.capacity = capacity.id) LEFT JOIN color ON (capacity.color = color.id) LEFT JOIN model ON (color.model = model.id) LEFT JOIN grade ON (phone.grade = grade.id) WHERE ";
$query_array = array();
for ($i = 0; $i < count($keywords); $i += 1) {
$query .= " ( phone.imei LIKE :search_" . $i;
$query .= " OR phone.sourcing LIKE :search_" . $i;
$query .= " OR phone.canal LIKE :search_" . $i;
$query .= " OR phone.entry LIKE :search_" . $i;
$query .= " OR phone.sale LIKE :search_" . $i;
$query .= " OR phone.state LIKE :search_" . $i;
$query .= " OR ( phone.snowden = 1 AND ':search_" . $i . "' = `snowden` )";
$query .= " OR model.name LIKE :search_" . $i;
$query .= " OR color.name LIKE :search_" . $i;
$query .= " OR capacity.amount LIKE :search_" . $i;
$query .= " OR grade.name LIKE :search_" . $i;
if ($i != (count($keywords) - 1)) {
$query .= " ) AND ";
} else {
$query .= " ) ";
}
if (strtolower($keywords[$i]) == 'snowden') {
$query_array['search_' . $i] = $keywords[$i];
} else {
$query_array['search_' . $i] = "%" . $keywords[$i] . "%";
}
}
$query .= "ORDER BY phone.id DESC";
$results = $stock->prepare($query);
$results->execute($query_array);
replace your line
$query .= " OR ( phone.snowden = 1 AND ':search_" . $i . "' = `snowden` )";
with
$query .= " OR ( phone.snowden = 1 AND 'snowden'= :search_" . $i )";
Databases:
listings
| ID | TITLE | COMPANY_ID |
| 1 | One | 1 |
| 2 | One | 1 |
| 3 | One | 1 |
Companies
| ID | NAME |
| 1 | One |
| 2 | Two |
| 3 | Three |
I have the PDO MYSQL statement:
"SELECT
listings.ID,
listings.TITLE,
listings.COMPANY_ID,
companies.ID,
companies.NAME
FROM listings INNER JOIN companies ON (listings.COMPANY_ID = companies.ID ) WHERE (listings.TITLE = :p1 AND companies.NAME = :p2 )LIMIT 10"
The associative array output:
Array
(
[ID] => 1
[TITLE] => analyst
[COMPANY_ID] => 1
[NAME] => one
)
Array
(
[ID] => 1
[TITLE] => analyst
[COMPANY_ID] => 1
[NAME] => one
)
Array
(
[ID] => 1
[TITLE] => analyst
[COMPANY_ID] => 1
[NAME] => one
)
When executing this query, my ID field that is being outputted to the PHP fetch associative array is being returned as 1.
With the exception to the ID, the output works as expected.
Why is my ID value changing?
______________________
METHOD:
protected function search_joined($parameters, $func){
$field = "*";
if(isset($parameters["fields"])){
if($parameters["fields"] != "*" && gettype($parameters["fields"]) == gettype(array())){
if(count($parameters["fields"]) == 2){
$field = "";
foreach($parameters["fields"] as $key=>$v){
foreach($v as $v_){
$field.= $parameters["tables"][$key] . "." . $v_ . ",";
}
}
$field = rtrim($field, ",");
}
}
}
$cond_ = "";
$values = array();
if(gettype($parameters["condArry"]) == gettype(array())){
$COND_TYPE = " AND ";
foreach($parameters["condArry"] as $v){
$operator = " = ";
if($v[1][0] == "%" || substr($v[1], -1) == "%"){
$operator=" LIKE ";
}
if(substr($v[1], 5) == "L::_>"){
$operator=" > ";
$v[1] = str_replace($v[1], "L::_>", "");
}
if($v[1][0] == "!"){
$operator=" != ";
//$v[1] = str_replace($v[1], "!", "");
$v[1] = substr($v[1], 1);
}
$COND_TYPE = (
(isset($v[2]))?
(
($v[2] == "&")? " AND " :
(
(($v[2]=="||")? " OR ": "")
)
): " AND "
);
$unique = md5($v[0] . $v[1]);
$cond_.= $v[0] . $operator . ":".substr($v[0], strpos($v[0], ".") + 1).$unique. " " . $COND_TYPE . " ";
$values[':'.substr($v[0], strpos($v[0], ".") + 1).$unique] = $v[1];
}
$cond_ = "WHERE (" . substr($cond_, 0, strlen($COND_TYPE)*(-1)) . ")";
}
//$cond_ = rtrim($cond_, ",");
$joiner = $parameters["tables"][0] . "." . $parameters["joiner"][0] . "=" . $parameters["tables"][1] . "." . $parameters["joiner"][1] . " ";
$sql = "SELECT ". $field . " FROM " . $parameters["tables"][0] . " INNER JOIN " . $parameters["tables"][1] . " ON (" . $joiner . ") " .$cond_ . (isset($parameters["LIMIT"])? "LIMIT " . $parameters["LIMIT"]: "");
echo $sql;
if(isset($parameters["test"])){
if($parameters["test"] == true){
echo "<br>". $sql . "<br>";
}
}
//echo "<br>". $sql . "<br>";
$q = $parameters["connection"]->prepare($sql);
foreach($values as $key => $v){
$q->bindvalue($key, $v);
echo "<br>" . $key . " : " . $v . "<br>";
}
$q->execute();
while($row = $q->fetch(PDO::FETCH_ASSOC)) {
if(!$func($row)){
break;
}
}
$conTableArry = null;
}
CALLER:
$params_= array(
"connection"=>$this->connection_,
"tables"=>array("listings", "companies"),
"joiner"=>array("COMPANY_ID","ID"),
"fields"=> array(
array(
"ID",
"TITLE",
"PAYMIN",
"PAYMAX",
"GEO_LOCATIONS_ID",
"CRIMINAL_HISTORY_REQ",
"EVAL_EXAM_REQ",
"AGE_REQ",
"EX_REQ",
"DRIVERS_LICENSE_REQ",
"CERTIFICATE_REQ",
"EDUCATION_REQ",
"RESUME_REQ" ,
"POSITIONS",
"COMPANY_ID"
),
array(
"ID",
"NAME"
)
),
"condArry"=>array(array("listings.TITLE", "analyst"), array("companies.NAME", "suitespec")),
"LIMIT"=>$LIMIT,
);
parent::search_joined($params_, function($r){
out($r);
return true;
});
You've got some confusing syntax in your SQL
SELECT
listings.ID,
listings.TITLE,
listings.COMPANY_ID,
companies.ID,
companies.NAME
FROM listings
INNER JOIN companies ON (listings.COMPANY_ID = companies.ID )
WHERE (listings.TITLE = :p1 AND companies.NAME = :p2 )
LIMIT 10
You have two ID columns and no aliasing. So you're likely getting the second ID back. Try aliasing the second ID column and trying again
SELECT
listings.ID,
listings.TITLE,
listings.COMPANY_ID,
companies.ID AS comp_id,
companies.NAME
You should be able to solve this by using unique column names for your result set (you currently use ID twice).
Change your SQL to something like this:
"SELECT
listings.ID,
listings.TITLE,
listings.COMPANY_ID,
companies.ID AS CID,
companies.NAME
FROM listings
INNER JOIN companies ON (listings.COMPANY_ID = companies.ID )
WHERE (listings.TITLE = :p1
AND companies.NAME = :p2 )LIMIT 10"
Notice the 5th line of that. I've changed it from companies.ID to companies.ID AS CID.
I'm trying to have an advanced sidebar that filters the results when someone uses the search bar. I have the regular search working and also made it display the count of items in a category on another sidebar (i.e. price range, brand, condition) but now i want the user to click a category and narrow down the results like what you see on newegg.com.
This is my search query:
function build_query($product_search) {
$search_query = "SELECT * FROM tbl_product p INNER JOIN tbl_brand b ON p.br_id = b.br_id";
$clean_search = str_replace(',', ' ', $product_search);
$search_word = explode(' ', $clean_search);
$final_search_words = array();
if (count($search_word) > 0) {
foreach ($search_word as $word) {
if (!empty($word)) {
$final_search_words[] = $word;
}
}
}
$where_list = array();
if (count($final_search_words) > 0) {
foreach($final_search_words as $word) {
$where_list[] = "p.pd_name LIKE '%$word%'";
}
}
$where_clause = implode(' OR ', $where_list);
if(!empty($where_clause)) {
$search_query .= " WHERE $where_clause";
}
Same thing for my sidebar that counts the categories:
function narrow_query($product_search) {
$search_query = "SELECT p.pd_name, p.pd_con, b.br_name AS name, c.cat_name AS cat,
COUNT(p.pd_con) AS con, COUNT(b.br_name) AS brand, COUNT(c.cat_name) AS cat_c,
COUNT(CASE WHEN p.pd_price >= '00.01' AND p.pd_price <= '99.99' THEN 1 END) AS cnt1,
COUNT(CASE WHEN p.pd_price >= '100.00' AND p.pd_price <= '199.99' THEN 1 END) AS cnt2,
COUNT(CASE WHEN p.pd_price >= '200.00' AND p.pd_price <= '299.99' THEN 1 END) AS cnt3,
And so on and so on...
FROM tbl_product p JOIN tbl_brand b ON b.br_id = p.br_id
JOIN tbl_category c ON c.cat_id = p.cat_id";
$clean_search = str_repl...
(Same word filter code as above)
Now i had something going that kinda worked by grabbing the $_GET:
"<a href=\"" . $_SERVER['PHP_SELF'] . "?productsearch=" . $product_search . "&narrow=" . $row['cat'] . "$link=1\">"
and using case in my functions:
function any_query($product_search, $link, $narrow) {
previous info from above...
if(!empty($link)) {
switch($link)
case 1:
$search_query .= " AND b.br_name = '$narrow'";
break;
default:
}
}
but it's not doing the job and I'm just lost at this point.
Is there a better way or a different method to achieve this? It doesn't have to use case or $_GET.
Thank you for your time.
The problem is you need to add a parentheses around your OR statements. I would do this:
$search_query .= ' WHERE 1';
if (!empty($where_clause)) {
$search_query .= " AND ($where_clause)";
}
if (!empty($narrow)) {
$search_query .= " AND $narrow";
}