mysql select multiple values from array match - php

I have an array lets say: Array ( [0] => 9 [1] => 7 [2] => 8 )
I want to SELECT from a table (users) all phone numbers where userID matches one from the array (if there is a phone number listed).
I want to do this without selecting all of the users from the database and only those that match that of the array and with actual phone numbers, should I do this in a loop?
Typically when I am doing an UPDATE, I do them within a foreach loop. Like so:
foreach($userArr as $user) {
$pid = $user;
if(!$statement->execute()) {
throw new Exception($statement->error, $statement->errno);
}
}
$statement->close();
Can we do SELECT like that as well?
Thanks in advance for any advice.

If you want to select all these users, just do the follow:
$idList = implode(',', $yourArray);
$sql = "SELECT * FROM users WHERE id IN($idList)";
// execute this $sql query

Try this:
<?php
$array = array(9, 7, 8);
$query = "SELECT * FROM mytable WHERE id = ";
$condition = implode(' OR id = ', $array);
$query .= $condition;
echo $query;
?>
Output:
SELECT * FROM mytable WHERE id = 9 OR id = 7 OR id = 8

You should do the following:
Build a string to express the userid seperated by comma. - Loop will be needed. i.e id1, id2, id3
Build the query string to search for them.
Example:
SELECT * FROM `Users` WHERE id IN (id1, id2, id3)

Related

SELECT a value multiple time in SQL

I have a code in PHP where I want to display multiple times values, and so, even if these values are the same between them. My code is simple :
$sql = "SELECT photo from table WHERE username IN ('1','2','2') ORDER BY id DESC ";
$res = array();
$result = mysqli_query($con,$sql);
while($row = mysqli_fetch_array($result)){
array_push($res, $row['photo']);
}
echo json_encode($res);
But this code only display (in json) an array of two values (because the values of photo of the username 2 are the same).
What I want to achieve is to make an array with the exact same number of values of the number of username I defined WHERE username IN ('1','2','2') (so here, 3 values).
I hope you understood me, thanks for helping me !
I think what you're after is to list even the duplicates in the end result. As your SQL will only retrieve the unique items, the idea would be to include the username in the SQL result set. Then use the original list of user names ($userNames) and add in the photo for each of them.
I've used mysqli_fetch_all() to simplify the process of fetching all of the data, then used array_column() to make the username the key for the photos.
$userNames = array(1,2,2);
$sql = "SELECT username, photo
from table
WHERE username IN ('".implode("','", $userNames)."')
ORDER BY id DESC ";
$res = array();
$result = mysqli_query($con,$sql);
$photos = mysqli_fetch_all($result, MYSQLI_ASSOC);
$photos = array_column($photos, "photo", "username");
foreach ( $userNames as $user ) {
if ( isset($photos[$user])) {
$res[] = $photos[$user];
}
else {
$res[] = '';
}
}
echo json_encode($res);
You would use left join:
select t.photo
from (select '1' as username union all select '2' union all select '3'
) u left join
table t
on t.username = u.username
order by t.id desc;
Note this will return rows, even when the user name does not exist. If you want to filter those rows, remove the left so you are doing an inner join.

How to SELECT same IDs from database which are stored in Array?

I have stored IDs as STRING of users who rated a post. Example:
$ids="5,8,4,9,7,8,87";
and I later convert the string into an array:
$kaboom = explode(',',$ids);
Now I want to query another table and select all field where the id is found in array $kaboom. I tried but I get the following error:
Notice: Array to string conversion in C:\xampp\htdocs\cebs\include\post_reacts.php on line 22
This is my code:
<?php
//include connection file
include 'dbc.php';
if(isset($_POST['post_id'])){
$post_id = $_POST['post_id'];
//SELECT ALL IDS OF THOSE WHO RATED THE POST
$query = mysqli_query($dbc_conn,"SELECT highlight_voters FROM $public_feed_table WHERE id='$post_id' LIMIT 1");
if($query==true){
while($row=mysqli_fetch_assoc($query)){
$ids = $row['highlight_voters'];
$kaboom = explode(",",$ids);
//select IDS which is/are in array and and get details about the ID
$check_ids_which_in_array = mysqli_query($dbc_conn,"SELECT * FROM $table_name WHERE id='$kaboom' ");
}
if($check_ids_which_in_array==true){
while($b=mysqli_fetch_assoc($check_ids_which_in_array)){
$person_who_rated =$b['id'];
//do something here after...
}
}
}
}
?>
You can use IN(...)
mysqli_query($dbc_conn, "SELECT * FROM $table_name WHERE id IN($ids)")
A query that uses IN would look like this:
SELECT * FROM table WHERE id IN(1, 2, 3, 7, 8, 9)
Therefore, you don't need to explode into an array beforehand.

MySql NOT IN many values from the mysql fetched result

I have 2 MySql queries which are interdependent.
My 'table1'
----------
id
----------
1
2
3
4
5
6
7
My First query
$sql1 = "SELECT * FROM table1 WHERE";// some condition which gives me id's 1,2,3
$res1=$obj->_executeQuery($sql1);
$res1=$obj->getAll($res1);
The result of this is giving me array
Array
(
[0] => Array
(
[id] => 1
..
..
)
[1] => Array
(
[id] => 2
..
..
)
[2] => Array
(
[id] => 3
..
..
)
)
I want to run another query on same 'table1', where not equal to list of ID's which i am getting from the first query.
My Second Query
$sql2 = "SELECT * FROM table1 WHERE id NOT IN (" . implode(',', $res1) . ")";
This is not showing me only one id i,e first. In above case i should get id's 4,5,6,7
Since implode will not give the desired value on multidimensional array so first you need to get the array of all id's to form one-dimensional array then use implode on the array of id's:
$id=array();
foreach ($res1 as $key=>$inner_array){
$id[]= $inner_array['id'];
}
you can use array_walk also here like this:
array_walk($res1,function($c) use (&$id) {$id[] = $c['id'];});
but i think the best one is array_map :
$id = array_map(function($i) {
return $i['id'];
}, $res1);
$sql2 = "SELECT * FROM table1 WHERE id NOT IN (" . implode(',', $id) . ")";
Note: when ever you are doing select please specify your column if you need few to select,unnecessarily selecting all will slow your sql processing.
suppose here:SELECT * FROM table1 WHERE, if you need only id then please select id only.
You have to change $res1, which is a two-dimensional array, into a one-dimensional array of IDs to be able to use implode:
$ids_from_first_query = array();
foreach($res1 as $result_row) {
$ids_from_first_query[] = $result_row['id'];
}
$ids_as_string = implode(',', $ids_from_first_query);
$sql2 = 'SELECT * FROM table1 WHERE id NOT IN(' . $ids_as_string . ')';
In the above code, $ids_as_string will look like this:
1,2,3
Thus it can be used in your MySQL query
Here you are getting two dimensional array so that's reason it is not working
while($each=mysql_fetch_array($res1))
{
$array[]=$each[id];
}
$imp=implode(",",$array);
$sql2 = "SELECT * FROM table1 WHERE id NOT IN (".$imp.")";
Try this it will works

SQL: can I JOIN 2 tables according the first table "array" value?

Im trying to find a better way to return 2 tables at once.
My first table is:
[ID] [area]
1 13,12,15
6 18,17,13
and the second table is:
[areaname] [singlearea]
textOf12 12
textOf18 18
textOf15 15
Now, I need to return for each [ID] hits area names, for example:
For the ID: 1, I need the following array: (textOf12,textOf15)
and for the ID 6 I need: (textOf18) only.
This is what i have for now (I don't think its a nice code):
$getall = "SELECT * FROM table1";
$resultfull = mysql_query($getall);
while ($res = mysql_fetch_assoc($resultfull))
{
$uarray = array();
$sqlarea = explode(",", $res['area']);
foreach($sqlarea as $userarea)
{
$areaarray = runquery("SELECT areaname From table2 WHERE singlearea = '".$userarea."'");
$value = mysql_fetch_object($areaarray);
array_push($uarray,$value->areaname);
}
var_dump($uarray);
any suggestions?
Thank you very much!
Comma separated ID list and ID value pretty good matching using like:
select t1.id, t2.areaname
from table1 t1, table2 t2
where concat(',', t1.area, ',') like concat('%,', t2.singlearea, ',%')
However It's recommended to use additional link table!

MySQL (exploding/matching array)

Question1:
MySQL table
id | array
1 | 1,2,3
2 | 2
3 | 2,3
4 | 4,5,6
$_GET['id'] = 2;
$a = mysql_query("SELECT * FROM `table` WHERE `array` ??? '$_GET[id]'");
In this step, I want to run through the entire array and see if it matches with the $_GET['id'], so it should output:
ids: 1,2,3
Question2:
MySQL table
id | array
1 | 4,5,6
2 | 3,4,7
$_GET['id'] = 4;
$a = mysql_query("SELECT * FROM `table` WHERE `array` ??? '$_GET[id]'");
In this step, I only want to match against the first element in the array, so it should output:
id: 4
I can only think of using PHP to do this, but I'd rather do all that just within the MySQL query, if that is even possible.
$a = mysql_query("SELECT * FROM `table`");
while($b = mysql_fetch_assoc($a))
{
$elements = explode(',', $b['array']);
foreach($elements as $element)
{
if($element == $_GET['id'])
{
echo $b['id'].'<br />';
}
}
}
or
$a = mysql_query("SELECT * FROM `table`");
while($b = mysql_fetch_assoc($a))
{
$array = $b['array'];
if(in_array($_GET['id'], $array))
{
echo $b['id'].'<br />';
}
}
that would look just awful.
That you can/should structure your database differently has already been mentioned (see http://en.wikipedia.org/wiki/Database_normalization). But....
See FIND_IN_SET()
mysql> SELECT FIND_IN_SET('b','a,b,c,d');
-> 2
e.g.
<?php
$mysql = init();
bar($mysql, 1);
bar($mysql, 2);
bar($mysql, 3);
bar($mysql, 4);
function bar($mysql, $x) {
$sql_x = mysql_real_escape_string($x, $mysql);
$result = mysql_query("SELECT id, foo FROM soTest WHERE FIND_IN_SET('$sql_x', foo)", $mysql) or die(mysql_error());
echo "$x:\n";
while( false!==($row=mysql_fetch_array($result, MYSQL_ASSOC)) ) {
echo $row['id'], ' ', $row['foo'], "\n";
}
echo "----\n";
}
function init() {
$mysql = mysql_connect('localhost', 'localonly', 'localonly') or die(mysql_error());
mysql_select_db('test', $mysql) or die(mysql_error());
mysql_query('CREATE TEMPORARY TABLE soTest (id int auto_increment, foo varchar(64), primary key(id))', $mysql) or die(__LINE__.' '.mysql_error());
mysql_query("INSERT INTO soTest (foo) VALUES ('1,2,3'), ('2,4'), ('3'), ('2,3'), ('1,2')", $mysql) or die(__LINE__.' '.mysql_error());
return $mysql;
}
prints
1:
1 1,2,3
5 1,2
----
2:
1 1,2,3
2 2,4
4 2,3
5 1,2
----
3:
1 1,2,3
3 3
4 2,3
----
4:
2 2,4
----
MySQL can't use indices to perform this search, i.e. the query results in a full table scan, see Optimizing Queries with EXPLAIN
edit:
For your second question you only have to change the WHERE-clause to
WHERE FIND_IN_SET('$sql_x', foo)=1
Your data structure in the DB is not optimal for querying the way you want it.
For the first question:
mysql_query("SELECT * FROM table WHERE array LIKE '%,$_GET[id],%' OR array LIKE '$_GET[id],%' OR array LIKE '%,$_GET[id]' OR array = '$_GET[id]'");
For the second:
mysql_query("SELECT id, SUBSTR(array, 1, POSITION(',' IN array) - 1) AS array FROM table WHERE array LIKE '$_GET[id],%' OR array = '$_GET[id]'");
As you can see, these queries aren't pretty, but they'll do what you want.
Untested, but you should be able to use:
Question 1:
SELECT * FROM table WHERE array REGEXP '(^|,)?(,|$)';
// Match either the start of the string, or a , then the query value, then either a , or the end of the string
Question 2:
SELECT * FROM table WHERE array REGEXP '^?(,|$)';
// Match the start of the string, then the query value, then either a , or the end of the string
Where ? is replaced with your $_GET value.
No idea on the performance of this.
I'd recommend you to bring your database to the first normal form, e. g.
CREATE TABLE t_master (
id INT PRIMARY KEY AUTO_INCREMENT
);
CREATE TABLE t_array (
id INT PRIMARY KEY AUTO_INCREMENT,
master_id INT NOT NULL,
value INT,
CONSTRAINT fk_array_master_id FOREIGN KEY (master_id) REFERENCES t_master (id)
);
Then you can find records in t_master that have a specific value with
$q = 'SELECT m.* ' .
'FROM t_master AS m INNER JOIN t_array AS a ON a.master_id = m.id ' .
"WHERE a.value = '" . mysql_real_escape_string($_GET['id'], $db) . "' " .
'GROUP BY m.id';
The most important advantage is that if you have a lot of values, you can add an index to find them much faster:
ALTER TABLE t_array ADD INDEX idx_value (value);
A less evident, but not the last advantage is that your queries become more logical and structured.
If you can't normalise your schema (which is the best option:
SELECT *
FROM table
WHERE ','+array+',' LIKE '%,$_GET[id],%'
But if you need to access the records by id, then you really should normalise
First One:
SELECT * FROM table WHERE array LIKE '$_GET[id],%' OR array LIKE '%,$_GET[id],%' OR array LIKE '%,$_GET[id]' OR array = '$_GET[id]
Second One:
SELECT * FROM table WHERE array LIKE '$_GET[id],%' OR array = '$_GET[id]
Explanation:
'$_GET[id],%' will match, if array is start with $_GET[id]
'%,$_GET[id],%' will match, if $_GET[id] is between any two of array items
'%,$_GET[id]' will match, if array is end with $_GET[id]
array = '$_GET[id]' match, if the array contains only one item equal to $_GET[id]

Categories