PHP MySQL check if items in array exist in Table, THEN SHOW - php

PHP 5.4 with MySQL
Building off of this:
<?php
$arr = ...
$sql = 'SELECT COUNT(*) FROM table WHERE field IN ( ' . implode( ',', $arr ) . ' );';
$result = $db->query( $sql );
?>
How would I display which items of the array ARE NOT in the table?

Instead of returning the count, return the field itself:
$sql = 'SELECT field WHERE field IN ' . implode( ',', $arr ) . ' );';
$result = $db->query($sql);
$found = array();
while ($row = $result->fetch_assoc()) {
$found[] = $row['field'];
}
Then you can compare the two arrays:
$not_found = array_diff($arr, $found);

If your $arr variable is sanitized and safe to build a query with, you can use union operators to build a table containing all the words in the array, then you can left join that table to table.field and only keep array items where there was no match.
$arr = array('one','two');
$sql = "select item from (
select '" . implode("' item union select '",$arr). "' item
) t1 left join table t2 on t2.field = t1.item
where t2.field is null";
this will produce the following sql
select item from (select 'one' item union select 'two' item) t1
left join table t2 on t2.field = t1.item
where t2.field is null

Just to give an idea (this probably won't work)
$arr = ...
$sql = 'SELECT field FROM table WHERE field IN ( ' . implode( ',', $arr ) . ' );';
$result = $db->query( $sql );
while($r = $result->fetch())
$arr2[] = $r['field'];
print_r(array_diff($arr,$arr2));

after you've done imloud, array ceases to be an array, this is a string, so you do not have to select count(*). You need to select id after do the while and compare arrays

Just use "NOT IN", if your items is up to 10 elements:
<?php
$arr = array('one','two');
$filterExisting = "'" . implode("', '", $arr ) . "'";
$sql = "SELECT COUNT(*) FROM table WHERE field NOT IN (". $filterExisting .")";
$result = $db->query($sql);
?>

Related

pdo query not executing when passing a variable as the query

I have a pdo command like this $sql = $pdoObj->execute($query) but it does not work, 0 result returning. I echo'ed out the $query variable just before calling execute() and then pasted it inside the execute() and the code ran successfully. I can't understand what is the problem here as I have done this in other parts of my code without problems.
Here are some examples of the queries:
SELECT s.id, s.marca, s.colore, s.prezzo, i.id_scarpa, i.taglia FROM scarpe AS s INNER JOIN info_scarpe AS i ON i.id_scarpa = s.id WHERE 1 = 1 AND taglia IN ('40','41','42') AND colore IN ('rosso', 'nero')
SELECT * FROM scarpe WHERE 1=1
SELECT * FROM scarpe WHERE 1=1 AND marca IN ('adidas','nike')
They are all dynamic generated queries based on the $_GET variable.
EDIT:
Sure
if ( isset($_GET) ) {
if ( isset($_GET['taglia']) ) {
$query = "
SELECT
s.id, s.marca, s.colore, s.prezzo, i.id_scarpa, i.taglia
FROM
scarpe AS s
INNER JOIN
info_scarpe AS i
ON i.id_scarpa = s.id
WHERE
1 = 1
";
foreach ( $_GET as $index => $val ) {
$a = explode(',', $val);
$in = "'" . implode("','", $a) . "'";
$query .= ' AND '.$index.' IN ('.$in.')';
}
} else {
$query = " SELECT * FROM scarpe WHERE 1=1";
foreach ( $_GET as $index => $val ) {
$a = explode(',', $val);
$in = "'" . implode("','", $a) . "'";
$query .= ' AND '.$index.' IN ('.$in.')';
}
}
echo 'data loaded';
} else {
$query = " SELECT * FROM scarpe ORDER BY id DESC ";
}
EDIT2:
I use query() and not execute() but still does not work
The arguments for execute should be an array with query parameters. You mean to use either
$result = $pdoObj->query($query);
OR
$stmt = $pdoObj->prepare($query);
$stmt->execute();

Getting output from a query with an implode function in it

I'm trying to determine whether a combination of topics related to a forum is unique. This is done while adding topics to a forum. The uniqueness is checked with this code and query:
$options = array(); //here's your choices
$options[] = 'blablabla';
$options[] = 'blabla';
foreach($options as $key => $value)
{
echo '<li>' . $value . '</li>';
}
$sql_unique = "SELECT Forums_ForumID, list
FROM (
SELECT Forums_ForumID, GROUP_CONCAT( Topics_TopicID ) AS list
FROM (
SELECT *
FROM Topics_crosstable
ORDER BY Topics_TopicID
)H
GROUP BY Forums_ForumID
)A
WHERE list = (
SELECT GROUP_concat( TopicID )
FROM Topics
WHERE Name IN (";
$sql_unique .= implode(",",$options);
$sql_unique .= ") ORDER BY Forums_ForumID ASC )";
$result = mysql_query($sql_unique);
//print "$result";
//echo $result;
//echo mysql_num_rows($result);
//$assoc = mysql_fetch_assoc($result);
var_dump($result);
I'm sure the query works fine when using fixed values in WHERE. With the current code I can't get any output. The vardump gives a result 'false' no matter if the combination of topics is unique or not. I've been trying for days now, so I really help you can help me out!
Thanks in advance!
You have to quote your options if they are strings.
$sql_unique .= "'". implode("','", $options) ."'";

php using result from previous query in another query

I need to grab a result from one query and pop it into another.
first query
$query = 'SELECT * FROM singleprop.jos_mls WHERE MSTMLSNO = ' . $mlsnum . ';';
$result = mysql_query($query);
$row = mysql_fetch_row($result);
second query
$aquery = 'SELECT * FROM singleprop.jos_agents WHERE AGTBRDIDMM = ' . $row[0] . ';';
$aresult = mysql_query($aquery);
$agent = mysql_fetch_row($aresult);
I know about JOIN, but don't know how to apply it with a 3rd table. Does my model have something to do with $this->?
The code looks good. You could write a query using join, which you are aware of. What is the question?
SELECT *
FROM singleprop.jos_mls as mls JOIN singleprop.jos_agents
ON singleprop.jos_mls.KEY = singleprop.jos_agents.KEY
WHERE mls.MSTMLSNO = $mlsnum
where KEY is the join key
OR
SELECT *
FROM singleprop.jos_agents
WHERE AGTBRDIDMM = (
SELECT COL_NAME
FROM singleprop.jos_mls
WHERE MSTMLSNO = ' . $mlsnum . '
)
where COL_NAME is the column name for AGTBRDIDMM in the first table

Combine a variable with SELECT results into an INSERT statement

I have 3 tables:
Users - uID (INT AUTO_INCREMENT), name (VARCHAR)
Movies - mID (IN AUTO_INCREMENT), title (VARCHAR)
Watched - uID (INT), mID (INT)
I'm writing a php function that constructs a query which adds records of movies watched by a particular person. Here's what I've come up with so far:
function set_watched($name, $movies){
$sql = "SET #userid = (SELECT uID FROM users WHERE name = '$name' LIMIT 1); ";
$sql .= "INSERT INTO watched (uID, mID) VALUES ('";
foreach ($movies as $index => $movie){
}
}
My question:
Is there a way to combine the #userid variable with the results of a SELECT mID FROM MOVIES WHERE title = $movie OR title = $movie [generated with foreach]?
I don't want to generate separate SELECT statements for every movie title. Perhaps I don't even have to use the #userid variable at all?
Try something like this:
$sql = "INSERT INTO watched (uID, mID)
SELECT User.uID, Movies.mID
FROM (SELECT uID FROM Users WHERE Users.name = '$name' LIMIT 1) AS User, Movies
WHERE ";
foreach ($movies as $index => $movie){
$sql .= "Movies.title = '$movie' OR ";
}
$sql = substr($sql, 0, -4) . ";";
I prefer using arrays and imploding them for this sort of an application. Also, I wouldn't try and force these two things into one query. I would either:
Modify the function parameters to accept uID as its input, instead of name
Change the logic to two queries.
Besides, PHP's mysql_query function doesn't support multiple queries, so if you're using the standard mysql functions, you can't execute two queries with one call to mysql_query.
Running with case #2, you can use something like this (untested, of course):
$sql = 'SELECT uID FROM users WHERE name = "' . $name. '" LIMIT 1';
$result = mysql_query( $sql);
$row = mysql_fetch_row( $result);
mysql_free_result( $result);
$values_array = array();
foreach ($movies as $index => $movie)
{
$values_array[] = '( "' . $row['uID'] . '", "' . $movie . '")';
}
$sql = 'INSERT INTO watched (uID, mID) VALUES ' . implode( ', ', $values_array);
$result = mysql_query( $sql);

Optimize this SQL query

I've got a SQL query within a foreach loop. Sometimes there can be many, and I mean a lot of queries to do, depending on several criteria, up to 78 queries potentially.
Now, I know that premature optimisation is root cause of all evil, but I don't want to see 78 queries - it's just not healthy.
Here's the code:
$crumbs = explode(",", $user['data']['depts']);
foreach ($crumbs as &$value) {
$data = $db->query("SELECT id FROM tbl_depts WHERE id = '" . $value . "'");
$crumb = $data->fetch_assoc();
$dsn = $db->query("SELECT msg, datetime FROM tbl_motd WHERE deptid = '" . $value . "'");
$motd = $dsn->fetch_assoc();
if ($motd['msg'] != "") {
<?php echo $motd['msg']; ?>
}
}
Can I make it any better?
Use IN MySQL operator to search over a set of values for id:
$ids = '"' . implode('", "',$crumbs) . '"';
$query1 = "SELECT id FROM tbl_depts WHERE id IN (" . $ids . ")";
$query2 = "SELECT msg, datetime FROM tbl_motd WHERE deptid IN (" . $ids . ")";
And so you will not need to retrieve all data you need using foreach loop, so you will have only 2 queries instead of 78.
Example: I have a table named table with 10 records which ids are: 1,2,3,4,5,6,7,8,9,10 (auto-incremented). I know I need records with ids 1,5,8. My query will be:
$sql = "SELECT * FROM `table` WHERE id in (1,5,8);";
And I don't understand why do you need to use & operator in foreach loop if you don't modify the $crubms arrays values.
I think this is want you want.
SELECT msg, datetime
FROM tbl_depts td
INNER JOIN tbl_motd tm ON td.id = tm.deptid

Categories