How to use OR multiple times in a Where statement? - php

I want to do something like "Where conditions = '$condition' OR conditions = '$condition2' OR conditions = '$condition3' but that returns all entries in the database versus the ones i am looking for.. what i can i do to make this work?
$sql = "SELECT STRAIGHT_JOIN DISTINCT table1.person_id, table1.full_name,
table2.stuff_id, table2.stuff_name, table3.whatever_why,
table3.whatever_comments, table3.whatever_test_id
from table1
join table4 on table1.person_id = table4.person_id
join table2 on table4.stuff_id = table2.stuff_id
join table3 on table1.person_id = table3.person_id
WHERE conditions = '$condition' and ( (
table3.whatever_why like '%$q%'
OR table3.whatever_comments like '%$q%'
OR table3.whatever_name like '%$q%'
))
order by table3.id DESC limit $startrow, 10";
$result = mysql_query($sql);

you may use parenthesis to group up your logic.
just continuing to list OR statements will match the rows if any of those are true.

Where conditions in ('$condition1', '$condition2', '$condition3')

Related

PHP search box issuse

I have a problem with some php code. So, when I write some text inside search box I should get more results, but I only get 1. This happened to my when I added second query with INNER JOIN. I have no idea why I'm getting only 1 result instead of more, anyone can help?
When I remove second query, it shows me all results.
$STH = $DBH->prepare('SELECT * FROM tv_shows WHERE title like :q ORDER BY title ASC LIMIT 5');
$STH->setFetchMode(PDO::FETCH_OBJ);
$STH->execute(array(
':q' => "%$q%"
));
if($STH->rowCount()) {
while($row = $STH->fetch()) {
$poster = $row->poster;
$mtitle = $row->title;
$mrd = $row->release_date;
$mid = $row->id;
$genres = "";
$STH = $DBH->prepare('SELECT g.title from genres g INNER JOIN tv_show_genres tg ON g.id = tg.genre_id INNER JOIN tv_shows t ON t.id = tg.tv_show_id WHERE t.id = :tid');
$STH->setFetchMode(PDO::FETCH_OBJ);
$STH->execute(array(
':tid' => $mid
));
if($STH->rowCount()) {
while($row = $STH->fetch()) {
$genres .= $row->title.", ";
}
echo
'<li>
<span class="search-poster"><img src="'.$poster.'"></span>
<span class="search-title">'.$mtitle.' ('.$mrd.')</span>
<span class="search-genre">'.substr($genres,0,-2).'</span>
</li>';
}
}
}
You're using the same variable $STH for both queries. So when the outer loop gets back to the
while ($row = $STH->fetch())
line, $STH now refers to the second query. Since you've reached the end of the results from that query, calling fetch() here returns false, so this loop ends as well.
Just use different variable names, e.g. $show_STH and $genre_STH.
However, an even better solution is to use a single query.
SELECT s.poster, s.title AS show_title, s.release_date, g.title AS genre_title
FROM (SELECT *
FROM tv_shows
WHERE title like :q
ORDER BY title ASC
LIMIT 5) AS s
INNER JOIN tv_show_genres tg ON s.id = tg.tv_show_id
INNER JOIN genres g ON tg.genre_id = g.id
ORDER BY s.title
Most of the time when you find yourself performing queries in nested loops like this, you can replace it with a single query that joins the two queries.

Can i write two foreach in only one?

In my code I have this:
$im = $database->query("SELECT * FROM cms_messaggi_importanti WHERE messo_da = :id ORDER BY ID DESC", array("id"=>$functions->Utente("id")));
foreach($im as $imp){
$mex_i = $database->query("SELECT * FROM cms_messaggi WHERE id = :id ORDER BY ID DESC", array("id"=>$imp['id_mex']));
foreach($mex_i as $mex_imp){
}
}
Can I write this code in only one? Because I have to use a lot of variable with this method. Is there a solution to my problem? For example, using "JOIN"?
You can (and should) do your query in one go, and then iterate over those results:
$im = $database->query("
SELECT *
FROM cms_messaggi_importanti mi
LEFT JOIN cms_messaggi m ON m.id = mi.id_mex
WHERE messo_da = :id
ORDER BY mi.ID DESC,
m.ID DESC",
array("id"=>$functions->Utente("id")));
foreach($im as $imp){
//...
}
You will probably need to replace the SELECT * by a more precise column list, which will be the columns available in the result set.

Add 2 row counts together in MySql

I am adapting something and I need to add 2 row counts together in mysql. So far I have
<?
$result = mysql_query("SELECT * FROM Table1 WHERE Field1 ='2' ");
$num_rows = mysql_num_rows($result);
$result2 = mysql_query("SELECT * FROM Table2 WHERE Field2 ='6' ");
$num_rows2 = mysql_num_rows($result2);
$num_rows3 = ($num_rows + $num_rows2)
echo "$num_rows3";
?>
I can echo either $num_rows OR $num_rows2 fine but I need to do the calculation then echo $num_rows3.
I am probably doing something stupid here but I do not know mysql at all so I am trying to learn.
Thanks for the help!
You could also have one single query for both counts:
SELECT count(t1.id), count(t2.id)
FROM (SELECT id FROM Table1 WHERE Field1 ='2') t1,
(SELECT id FROM Table2 WHERE Field2 ='6') t2
Also note that you are missing a ; when summing the counts.
This is just a suggestion even though you got your answer.
If you want to add those into ONE MYSQLI query you could use this:
SELECT sum(cnt) from
(SELECT COUNT(*) cnt FROM T1 WHERE Field1=2 union all
SELECT COUNT(*) cnt FROM T2 WHERE Field2=6) a
I just don't see the point in fetching all data in SELECT * FROM Where all you do is mysql_num_rows($result)
Hope this helps, and maybe improves your code.
Good Luck!
Here is just a demo IN SQLFiddle, so you can see this in action:
SQLFiddle Demo
I was missing the ; after the calculation!!
Using only one query and counting before add, a possible code is
<?
$query = "SELECT c1 + c2 FROM ";
$query .= "(SELECT count(Field1) c1 FROM Table1 WHERE Field1 ='2') t1,";
$query .= "(SELECT count(Field2) c2 FROM Table2 WHERE Field2 ='6') t2";
$result = mysql_query($query);
$value = mysql_num_rows($result);
echo "$value";
?>

How can I convert these two queries in a loop into a single JOINed query?

I am currently trying to get data from my table (mostKills by Weapon in a table with over 300 kills). Initially I did a normal query
$q = $mysql->query("SELECT * FROM `kills`") or die($mysql->error);
but when I tried to
$query2 = $mysql->query("SELECT `killerID`, COUNT(`killerID`) AS tot_kills FROM `kills` WHERE `killText` LIKE '%$gun%' GROUP BY `killerID` ORDER BY `tot_kills` DESC;") or die($mysql->error);
$kData = $query2->fetch_assoc();
$query3 = $mysql->query("SELECT `Username` FROM `players` WHERE `ID` = '" . $kData['killerID'] . "'") or die($mysql->error);
$uData = $query3->fetch_assoc();
$array[$gun]['Kills']++;
$array[$gun]['Gun'] = $gun;
$array[$gun]['BestKiller'] = $uData['Username'];
$array[$gun]['killAmount'] = $kData['tot_kills'];
function sortByKills($a, $b) {
return $b['Kills'] - $a['Kills'];
}
usort($array, 'sortByKills');
foreach($array as $i => $value)
{
// table here
}
I had to do it in a while loop, which caused there to be around 600 queries, and that is obviously not acceptable. Do you have any tips on how I can optimize this, or even turn this into a single query?
I heared JOIN is good for this, but I don't know much about it, and was wondering if you guys could help me
Try this...
I added a inner join and added a username to your select clause. The MIN() is just a way to include the username column in the select and will not have an impact on you result as long as you have just 1 username for every Killerid
SELECT `killerID`
, COUNT(`killerID`) AS tot_kills
, MIN(`Username`) AS username
FROM `kills`
INNER JOIN `players`
ON `players`.`id` = `kills`.`killerid`
WHERE `killText` LIKE '%$gun%'
GROUP BY `killerID`
ORDER BY `tot_kills` DESC
SELECT kills.killerID, count(kills.killerID) as killTotal, players.Username
FROM kills, players
WHERE kills.killText
LIKE '%$gun%'
AND players.ID` = kills.killerID
GROUP BY kills.killerID
ORDER BY kills.tot_kills DESC
Here is a good place to learn some more about joins.
http://www.sitepoint.com/understanding-sql-joins-mysql-database/
The best way is to have your own knowledge so you can be able to tune up your select queries.
Also put more indexes to your DB, and try to search and join by index.

How to convert normal sql query to Zend_Db_Select?

Hi I want to convert my normal mysql query to zend.db.select;
I want to use this script:
$select = $db->select();
// Add a FROM clause
$select->from( ...specify table and columns... )
// Add a WHERE clause
$select->where( ...specify search criteria... )
// Add an ORDER BY clause
$select->order( ...specify sorting criteria... );
$select->limit(20, 10);
for my query below
SELECT
IF(derived_messages.toid = '$user', derived_messages.fromid,
derived_messages.toid) friend1,c.UserName,
derived_messages.message, derived_messages.fromid, derived_messages.toid,
derived_messages.is_read,derived_messages.type,derived_messages.id as mesid,
derived_messages.date,
(SELECT M.message_id FROM messagesmapped M where M.message_id= derived_messages.id AND M.user_id ='$user' AND M.important = 1) as MesMapid
FROM
(
SELECT *
FROM messages
WHERE messages.deleted_by NOT
IN ( $user )
ORDER BY Date DESC
) derived_messages
INNER JOIN Users c ON c.MemberID = IF(derived_messages.toid = '$user', derived_messages.fromid,
derived_messages.toid)
WHERE (derived_messages.id IN
(SELECT M.message_id FROM messagesmapped M where M.message_id= derived_messages.id AND M.user_id ='$user' AND M.important = 1)
AND
(derived_messages.toid='$user' OR derived_messages.fromid='$user'))
GROUP BY friend1 ASC
ORDER BY derived_messages.date DESC, derived_messages.id DESC LIMIT $limit $offset
I hope someone can help m on this.
Thank you.
It's possible but unlikely someone will write the query for you.
My recommendation on tackling such a query is to write each individual subquery as its own Zend_Db_Select object and then build the final query using the subqueries that you already have objects for.
Zend_Db_Select doesn't directly support the IF function, so for that you will need to use Zend_Db_Expr to add that statement into your select.
Here is a basic example of what I am talking about. Let's build the following query:
SELECT IF(msg.toId = 'drew010', msg.fromId, msg.toId), id, name, age, history.ip
FROM users
JOIN history ON users.id = history.userId
WHERE users.id = (
SELECT id FROM users WHERE loginCount > 1000
)
GROUP BY id,
ORDER BY age DESC
First build the subselect that select users where loginCount > 1000.
$subquery1 = $db->select()
->from('users', array('id'))
->where('loginCount > ?', 1000);
Next, build the outer query with the IF function:
$cols = array(
new Zend_Db_Expr('IF(' . $db->quoteInto('msg.toId = ?', 'drew010') . '), msg.fromId, msg.toId'),
'id', 'name', 'age'
);
$query = $db->select()
->from('users', $cols)
->join('history', 'users.id = history.userId', array('ip'))
->where('id = ?', $subquery1)
->group('id')
->order('age DESC');
echo $query;
The output:
SELECT
IF(msg.toId = 'drew010', msg.fromId, msg.toId),
`users`.`id`,
`users`.`name`,
`users`.`age`,
`history`.`ip`
FROM `users`
INNER JOIN `history`
ON users.id = history.userId
WHERE id = (
(SELECT `users`.`id`
FROM `users`
WHERE (loginCount > 1000))
)
GROUP BY `id`
ORDER BY `age` DESC
So the way to go is break the entire query into individual queries first, and then construct the outer query. Just have patience and take it slow. That and read over the Zend_Db_Select docs to get a full picture of what you have available to you.

Categories