I have written a SELECT Query to concatenate a person's name and email address. I then want to echo this string.
Here is the code:
$sqldiv = "Select concat(p1.display_name, " - ", p1.user_email) AS Contact FROM wp_players p1
JOIN wp_divisions2 d2 ON p1.id = d2.div_player1_id
JOIN wp_leagues lg ON d2.div_league_ID = lg.league_id
WHERE d2.player_div_id = 2105
ORDER BY d2.div_wins DESC, d2.div_loss ASC, d2.div_rating DESC";
$resdiv = mysqli_query($link, $sqldiv);
$div = array();
while ($rowdiv = mysqli_fetch_array($resdiv)) {
$div[] = $rowdiv[0];
}
echo var_dump($div[0]);
If I use this SELECT QUERY it works:
$sqldiv = "Select p1.display_name FROM wp_players p1
JOIN wp_divisions2 d2 ON p1.id = d2.div_player1_id
JOIN wp_leagues lg ON d2.div_league_ID = lg.league_id
WHERE d2.player_div_id = 2105
ORDER BY d2.div_wins DESC, d2.div_loss ASC, d2.div_rating DESC";
$resdiv = mysqli_query($link, $sqldiv);
$div = array();
while ($rowdiv = mysqli_fetch_array($resdiv)) {
$div[] = $rowdiv[0];
}
echo var_dump($div[0]);
The only difference is that I am using concat. If I run the SELECT Query through SQL I get the output in a single string, which I assume is correct to set $div as an array.
What am I doing wrong?
Fatal error: Uncaught Error: Call to undefined method Magento\Framework\DB\Statement\Pdo\Mysql::fetch_assoc() in /var/www/html/magento22/mage.php:145
here is my code
$data = array();
/* ORDERS */
$result = $write->query('select c.sku, v.value, if(iv.qty = 0 and
(if(iv.use_config_backorders = 1,\'Allow Backorder\',if(iv.backorders = 101,\'Allow pre-order\',\'No Backorder\'))) = \'No Backorder\'
, \'disabled\',\'enabled\') as status, iv.qty,
if(iv.use_config_backorders = 1,\'Allow Backorder\',if(iv.backorders = 101,\'Allow pre-order\',\'No Backorder\')) as stock_status,
if(e.product_id is null,\'No\',\'Yes\') in_wow,
d.value as pre_date
from catalog_product_entity c
join catalog_product_entity_varchar v on v.entity_id = c.entity_id and v.attribute_id = 71
join catalog_product_entity_int s on s.entity_id = c.entity_id and s.attribute_id = 96
join cataloginventory_stock_item iv on iv.product_id = c.entity_id
join catalog_product_entity_varchar d on d.entity_id = iv.product_id and d.attribute_id = 182
left join catalog_category_product e on e.product_id = c.entity_id and category_id = 61
join catalog_product_website w on w.product_id = c.entity_id
where c.type_id = \'simple\' and w.website_id = 1 and s.value = 1
');
if(is_object($result))
{
while ($resultsArray = $result->fetch_assoc())
{
if(empty($data))
$data[] = array_keys($resultsArray);
$data[] = $resultsArray;
} var_dump($data);
}
there is no connection problem and also my object $result has values. so no problem with that.
try changing: while ($resultsArray = $result->fetch_assoc())
to: while ($resultsArray = $result->fetchAll(\PDO::FETCH_ASSOC))
or could by while ($resultsArray = $result->fetch(\PDO::FETCH_ASSOC))
I would like to ask can I combine multiple IN operator with AND query?I need your help with my codes.Here is my code that I have tried but not working.
if ($areas != '' || $city_check != '' || $course != '' || $subject_check != '') {
$countcity = count($city_check);
$countsubject = count($subject_check);
$area_ids = implode(',',$city_check);
$subject_ids = implode(',',$subject_check);
$sql .= "AND TAC.tac_st_id = '".$areas."' AND TAC.tac_city_id IN($area_ids)
AND TRS.trs_tc_id = '".$course."' AND TRS.trs_ts_id IN($subject_ids)
GROUP BY U.u_username
HAVING COUNT(distinct TAC.tac_city_id) = '".$countcity."' COUNT(distinct TRS.trs_ts_id) = '".$countsubject."'
";
}
It produce no result.
I have done below code that working like I want but it can only run each blocks inside if.So if I want to search for city_check, the subject_check will not working and vice versa.
//search for cities
// if ($areas != '' || $city_check != '') {
// $countcity = count($city_check);
// $sql .= "AND TAC.tac_st_id = '".$areas."' AND TAC.tac_city_id IN(".implode(',',$city_check).")
// GROUP BY U.u_username
// HAVING COUNT(distinct TAC.tac_city_id) = '".$countcity."'
// ";
// }
//search for subject
// if ($course != '' || $subject_check != '') {
// $countsubject = count($subject_check);
// // echo json_encode(["message"=>$countcity]);
// $sql .= "AND TRS.trs_tc_id = '".$course."' AND TRS.trs_ts_id IN(".implode(',',$subject_check).")
// GROUP BY U.u_username
// HAVING COUNT(distinct TRS.trs_ts_id) = '".$countsubject."'
// ";
// }
What I want is that both cities and subject can be search together.Thank you for your help in advanced..
Edit: I try to output my SQL in phpmyadmin
SELECT U.u_username,U.u_email,U.u_status,ST.st_name,CT.city_name,TC.tc_title,TS.ts_title
FROM tk_user as U
INNER JOIN tk_user_details AS UD ON UD.ud_u_id = U.u_id
LEFT JOIN tk_tutor_subject AS TRS ON TRS.trs_u_id = U.u_id
LEFT JOIN tk_tution_course AS TC ON TC.tc_id = TRS.trs_tc_id
LEFT JOIN tk_tution_subject AS TS ON TS.ts_id = TRS.trs_ts_id
LEFT JOIN tk_tutor_area_cover AS TAC ON TAC.tac_u_id = U.u_id
LEFT JOIN tk_cities CT ON CT.city_id = UD.ud_city AND TAC.tac_city_id = CT.city_id
LEFT JOIN tk_states AS ST ON TAC.tac_st_id = ST.st_id
LEFT JOIN tk_countries AS C ON ST.st_c_id = C.c_id AND CT.city_c_id = C.c_id
WHERE U.u_status <> 'D'
AND TAC.tac_st_id = 1046 AND TAC.tac_city_id IN(16,17)
AND TRS.trs_tc_id = 5 AND TRS.trs_ts_id IN(8,9)
GROUP BY U.u_username
HAVING COUNT(distinct TAC.tac_city_id) = 2 AND COUNT(distinct TRS.trs_ts_id) = 2
If one of them could be empty you should use something like that:
Use OR
...
WHERE U.u_status <> 'D'
AND
(
(TAC.tac_st_id = 1046 AND TAC.tac_city_id IN(16,17) )
OR
(TRS.trs_tc_id = 5 AND TRS.trs_ts_id IN(8,9) )
)
...
There are 3 different filters: books, authors and stores (select lists), and I may use their all together at once or only one or two of them, so I use UNION to get together all queries
require('database.php');
if(isset($_POST['books'])){
$books_ids = $_POST["books"];
}
if(isset($_POST['authors'])){
$authors_ids = $_POST["authors"];
}
if(isset($_POST['stores'])){
$stores_ids = $_POST["stores"];
}
$query = "";
if( !empty( $books_ids ))
{
$books_ids_in = implode(',', array_fill(0, count($books_ids), '?'));
$query .= "SELECT
b.id,
b.`name`,
b.`year`,
GROUP_CONCAT(DISTINCT a.`name`) AS author_names,
GROUP_CONCAT(DISTINCT s.`name`) AS store_names,
'book' as param
FROM
books AS b
LEFT JOIN books_authors AS b_a ON b.id = b_a.book_id
LEFT JOIN authors AS a ON a.id = b_a.author_id
LEFT JOIN books_stores AS b_s ON b.id = b_s.book_id
LEFT JOIN stores AS s ON s.id = b_s.store_id
WHERE
b.id IN (". $books_ids_in .")
GROUP BY b.id
ORDER BY b.id";
}
if( !empty( $authors_ids ) )
{
$authors_ids_in = implode(',', array_fill(0, count($authors_ids), '?'));
if (!empty($query)) {
$query .= " UNION ";
}
$query .= "SELECT
b.id,
b.`name`,
b.`year`,
GROUP_CONCAT(DISTINCT a.`name`) AS author_names,
GROUP_CONCAT(DISTINCT s.`name`) AS store_names,
'author' as param
FROM
books AS b
LEFT JOIN books_authors AS b_a ON b.id = b_a.book_id
LEFT JOIN authors AS a ON a.id = b_a.author_id
LEFT JOIN books_stores AS b_s ON b.id = b_s.book_id
LEFT JOIN stores AS s ON s.id = b_s.store_id
WHERE
b.id IN (
SELECT DISTINCT book_id FROM books_authors WHERE author_id IN (". $authors_ids_in .")
)
GROUP BY b.id
ORDER BY b.id";
}
if( !empty( $stores_ids ) )
{
$stores_ids_in = implode(',', array_fill(0, count($stores_ids), '?'));
if (!empty($query)) {
$query .= " UNION ";
}
$query .= "SELECT
b.id,
b.`name`,
b.`year`,
GROUP_CONCAT(DISTINCT a.`name`) AS author_names,
GROUP_CONCAT(DISTINCT s.`name`) AS store_names,
'store' as param
FROM
books AS b
LEFT JOIN books_authors AS b_a ON b.id = b_a.book_id
LEFT JOIN authors AS a ON a.id = b_a.author_id
LEFT JOIN books_stores AS b_s ON b.id = b_s.book_id
LEFT JOIN stores AS s ON s.id = b_s.store_id
WHERE
b.id IN (
SELECT DISTINCT book_id FROM books_stores WHERE store_id IN (". $stores_ids_in .")
)
GROUP BY b.id
ORDER BY b.id";
}
if( !empty( $query )) {
$stmt = $conn->prepare($query);
if( !empty( $books_ids ))
{
foreach ($books_ids as $k => $id) {
$stmt->bindValue(($k+1), $id);
}
}
if( !empty( $authors_ids ))
{
foreach ($authors_ids as $k => $id) {
$stmt->bindValue(($k+1), $id);
}
}
if( !empty( $stores_ids ))
{
foreach ($stores_ids as $k => $id) {
$stmt->bindValue(($k+1), $id);
}
}
$stmt->execute();
$results = $stmt->fetchAll();
echo json_encode($results);
}
$conn = null;
code works just fine when I use only one filter, but when I try to use 2 or more, I get error
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens' in C:\xampp\htdocs\bookstore\filter.php:123 Stack trace: #0 C:\xampp\htdocs\bookstore\filter.php(123): PDOStatement->execute() #1 {main} thrown in C:\xampp\htdocs\bookstore\filter.php on line 123
I guess, something's wrong with bindValue using but I don't know how to fix that?
UPD
var_dump($query) (3 books and 2 authors chosen)
string(1097) "SELECT b.id, b.name, b.year, GROUP_CONCAT(DISTINCT a.name) AS author_names, GROUP_CONCAT(DISTINCT s.name) AS store_names, 'book' as param FROM books AS b LEFT JOIN books_authors AS b_a ON b.id = b_a.book_id LEFT JOIN authors AS a ON a.id = b_a.author_id LEFT JOIN books_stores AS b_s ON b.id = b_s.book_id LEFT JOIN stores AS s ON s.id = b_s.store_id WHERE b.id IN (?,?,?) GROUP BY b.id ORDER BY b.id UNION SELECT b.id, b.name, b.year, GROUP_CONCAT(DISTINCT a.name) AS author_names, GROUP_CONCAT(DISTINCT s.name) AS store_names, 'author' as param FROM books AS b LEFT JOIN books_authors AS b_a ON b.id = b_a.book_id LEFT JOIN authors AS a ON a.id = b_a.author_id LEFT JOIN books_stores AS b_s ON b.id = b_s.book_id LEFT JOIN stores AS s ON s.id = b_s.store_id WHERE b.id IN ( SELECT DISTINCT book_id FROM books_authors WHERE author_id IN (?,?) ) GROUP BY b.id ORDER BY b.id" 01201
There are problems with your code for building a dynamic query.
When building a dynamic query you need to separate those parts of the query that are static from those that are dynamic.
You can see that the following code is static.
$query = "SELECT
b.id,
b.`name`,
b.`year`,
GROUP_CONCAT(DISTINCT a.`name`) AS author_names,
GROUP_CONCAT(DISTINCT s.`name`) AS store_names,
'book' as param
FROM
books AS b
LEFT JOIN books_authors AS b_a ON b.id = b_a.book_id
LEFT JOIN authors AS a ON a.id = b_a.author_id
LEFT JOIN books_stores AS b_s ON b.id = b_s.book_id
LEFT JOIN stores AS s ON s.id = b_s.store_id ";
And also
" GROUP BY b.id
ORDER BY b.id";
The rest of the code is dynamic.
When filtering records the WHERE clause is used and the AND & OR operators are used to filter records based on more than one condition.
The AND operator displays a record if both the first condition AND the second condition are true.
The OR operator displays a record if either the first condition OR the second condition is true.
so for the first condition WHERE is used but after that AND or OR must be used(using OR in your example)
// Static code
sql = "SELECT * FROM `table`"
// Set initial condition to WHERE
clause = "WHERE";
if( !empty( filter )){
Add clause to sql
Add condition to sql
change clause to OR or AND as required
}
Repeat for each filter
Note the filter is not changed until a filter is not empty and remains changed once changed.
The remaining static code is added after all the filters have been handled
To allow different filters to be applied you can use a flag.
$flag = 0;
if(isset($_POST['books'])){
$books_ids = $_POST["books"];
$flag += 1;
}
if(isset($_POST['authors'])){
$authors_ids = $_POST["authors"];
$flag += 10;
}
if(isset($_POST['stores'])){
$stores_ids = $_POST["stores"];
$flag += 100;
}
Use "lazy" binding when possible - passing data into execute will dramatically shorten your code.
See PDO info
You require to merge array to perform this. Using switch statement with the flag you merge the arrays required.
switch ($flag) {
case 1:
$param_array = $books_ids;
break;
case 10:
$param_array = $authors_ids;
break;
case 100:
$param_array = $stores_ids;
break;
case 11://books & authors
$param_array = array_merge($books_ids, $authors_ids);
break;
case 101://books & stores
$param_array = array_merge($books_ids, $stores_ids);
break;
case 110://authors & stores
$param_array = array_merge($authors_ids, $stores_ids);
break;
case 111://books & authors & stores
$param_array = array_merge(array_merge($books_ids,$authors_ids),$stores_ids);
break;
}
if( !empty( $query )) {
$stmt = $conn->prepare($query);
$stmt->execute($param_array);
$results = $stmt->fetchAll();
echo json_encode($results);
}
The following code uses the above points. I have echoed some lines to indicate results which can be removed once testing is done.Also some code has been commented out for testing.
//Set flag
$flag = 0;
if(isset($_POST['books'])){
$books_ids = $_POST["books"];
$flag += 1;
}
if(isset($_POST['authors'])){
$authors_ids = $_POST["authors"];
$flag += 10;
}
if(isset($_POST['stores'])){
$stores_ids = $_POST["stores"];
$flag += 100;
}
echo $flag. " <BR>";//Remove after testing
//Basic SQL statement
$query = "SELECT
b.id,
b.`name`,
b.`year`,
GROUP_CONCAT(DISTINCT a.`name`) AS author_names,
GROUP_CONCAT(DISTINCT s.`name`) AS store_names,
'book' as param
FROM
books AS b
LEFT JOIN books_authors AS b_a ON b.id = b_a.book_id
LEFT JOIN authors AS a ON a.id = b_a.author_id
LEFT JOIN books_stores AS b_s ON b.id = b_s.book_id
LEFT JOIN stores AS s ON s.id = b_s.store_id ";
// Set initial condition to WHERE
$clause = "WHERE";
if( !empty( $books_ids ))
{
$books_ids_in = implode(',', array_fill(0, count($books_ids), '?'));
$query .= $clause;
$query .= " b.id IN (". $books_ids_in .")";
// Set condition to OR for additional condition
$clause = " OR ";
}
if( !empty( $authors_ids ) )
{
$authors_ids_in = implode(',', array_fill(0, count($authors_ids), '?'));
/* This part commented out as I don't see relevance
if (!empty($query)) {
$query .= " UNION ";
}
*/
$query .= $clause;
$query .= " b.id IN (
SELECT DISTINCT book_id FROM books_authors WHERE author_id IN (". $authors_ids_in .")
)";
// Set condition to OR for additional condition
$clause = " OR ";
}
if( !empty( $stores_ids ) )
{
$stores_ids_in = implode(',', array_fill(0, count($stores_ids), '?'));
/* if (!empty($query)) {
$query .= " UNION ";
}
*/
$query .= $clause;
$query .= " b.id IN (
SELECT DISTINCT book_id FROM books_stores WHERE store_id IN (". $stores_ids_in .")
)";
$clause = " OR ";
}
//Add GROUP & ORDER
$query .= " GROUP BY b.id
ORDER BY b.id";
echo $query; //Remove after testing
//building $param_array
switch ($flag) {
case 1:
$param_array = $books_ids;
break;
case 10:
$param_array = $authors_ids;
break;
case 100:
$param_array = $stores_ids;
break;
case 11://books & authors
$param_array = array_merge($books_ids, $authors_ids);
break;
case 101://books & stores
$param_array = array_merge($books_ids, $stores_ids);
break;
case 110://authors & stores
$param_array = array_merge($authors_ids, $stores_ids);
break;
case 111://books & authors & stores
$param_array = array_merge(array_merge($books_ids,$authors_ids),$stores_ids);
break;
}
echo "<br>";
print_r($param_array);// remove after testing
/*
if( !empty( $query )) {
$stmt = $conn->prepare($query);
$stmt->execute($param_array);
$results = $stmt->fetchAll();
echo json_encode($results);
}
$conn = null;
Don't use same $k; use a variable and increment it with each bind; See below
$bindingIndex = 0;
if( !empty( $books_ids ))
{
foreach ($books_ids as $k => $id) {
$stmt->bindValue((++$bindingIndex), $id);
}
}
if( !empty( $authors_ids ))
{
foreach ($authors_ids as $k => $id) {
$stmt->bindValue((++$bindingIndex), $id);
}
}
if( !empty( $stores_ids ))
{
foreach ($stores_ids as $k => $id) {
$stmt->bindValue((++$bindingIndex), $id);
}
}
i have a function where i get the ratings of the selected user by id,
it gets the ratings from one type of things, the ratings of a diff type of things and then does a+b
i know it's not very optimized but i'm focus on making all work...
this i do it like this
function votos_usuario($id){
$previa = "SELECT id FROM preguntas WHERE id_usuario = '$id'";
$r_previo = mysql_query($previa);
$ids_p = '0, ';
while($items_previos = mysql_fetch_array($r_previo)){
$ids_p .= $items_previos['id'].", ";
//echo "ids pregunta usuario: ".$items_previos['id']."<br>";
}
$ids = substr($ids_p,0,-2);
//echo $ids;
$consulta = "SELECT valor FROM votos_pregunta WHERE id_pregunta IN ( $ids )";
//echo $consulta;
$resultado = mysql_query($consulta);
$votos_preguntas = 0;
while($voto = mysql_fetch_array($resultado)){
$votos_preguntas = $votos_preguntas + $voto['valor'];
}
//$votos_preguntas= 0;
//$votos_preguntas = mysql_query("SELECT SUM(valor) FROM votos_pregunta WHERE id_pregunta IN (SELECT id FROM preguntas WHERE id_usuario = '$id')");
$previa_r = "SELECT id FROM recetas WHERE id_usuario = '$id'";
$r_previo_r = mysql_query($previa_r);
$ids_r = '0, ';
while($items_previos_r = mysql_fetch_array($r_previo_r)){
$ids_r .= $items_previos_r['id'].", ";
//echo "ids pregunta usuario: ".$items_previos['id']."<br>";
}
$ids = substr($ids_r,0,-2);
$consulta_b = "SELECT valor FROM votos_receta WHERE id_receta IN ( $ids )";
//echo $consulta;
$resultado_b = mysql_query($consulta_b);
$votos_recetas = 0;
while($voto_r = mysql_fetch_array($resultado_b)){
$votos_recetas = $votos_recetas + $voto_r['valor'];
}
$total = $votos_preguntas + $votos_recetas;
return $total;
}
Now the Question,
how can i do it to get all users ordered by rating desc ???? i just can't see it :S
SELECT uid, SUM(Votes)
FROM (
SELECT p.id_usuario uid, SUM(vp.valor) votes
FROM preguntas p JOIN votos_pregunta vp ON p.id = vp.id_pregunta
GROUP BY p.id_usuario
UNION ALL
SELECT r.id_usuario uid, SUM(vr.valor) votes
FROM recetas r JOIN votos_receta vr ON r.id = vr.id_receta
GROUP BY r.id_usuario
) rs
GROUP BY uid
ORDER BY SUM(Votes) DESC
instead of your php loop and all the sub queries, you can use this single query to get what you want:
SELECT (
SELECT SUM(vp.valor)
FROM preguntas p JOIN votos_pregunta vp ON p.id = vp.id_pregunta
WHERE p.id_usuario = '$id')
+ (
SELECT SUM(vr.valor)
FROM recetas r JOIN votos_receta vr ON r.id = vr.id_receta
WHERE r.id_usuario = '$id'
)
Also, when you're only using the associative keys in the result array, using mysql_fetch_assoc() is much, much faster than mysql_fetch_array().
Same applies to using mysql_fetch_row() instead when you're just using the numerical keys.