Wordpress query with variable in SQL - php

Why this code gives empty array:
$category = 3;
$man = 'HP';
$query_join = $wpdb->get_results('SELECT wp_products.product_manufacturer
FROM wp_products
JOIN wp_categories
ON wp_products.category_id=wp_categories.id
WHERE ' . $category . ' = wp_products.category_id
AND ' . $man . ' = wp_products.product_manufacturer
');
var_dump($query_join);
And this code gives array with one result:
$category = 3;
$query_join = $wpdb->get_results('SELECT wp_products.product_manufacturer
FROM wp_products
JOIN wp_categories
ON wp_products.category_id=wp_categories.id
WHERE ' . $category . ' = wp_products.category_id
AND "HP" = wp_products.product_manufacturer
');
var_dump($query_join);
What do I have to do with variable in first code to get result like in secound?

This:
AND ' . $man . ' = wp_products.product_manufacturer
would produce
AND HP = wp_products.product_manufacturer
^^----
Note the lack of quotes around HP, which makes the DB interpret that as a FIELD name.
Try
AND "' . $man . '" = wp_products.product_manufacturer
^------------^
note the extra quotes. And note that you are wide-open to sql injection attacks.

Related

Combine multiple SQL queries into single query for speed

I am working in PHP with Laravel and the page I have been given contains 3 SQL queries on separate tables but using the same criteria. I have tried combining them but the combined results are slower than the original. What can I do to increase rather than decrease the speed of these queries?
Here are my queries:
$searchFor = 'debtor_name';
$searchForBKR = 'estate_name';
$searchForHypotech = 'hypleg_lot_credit_debtor_name';
$arraySearch = explode(",", $request->input('name'));
$search = $searchFor . ' like "%';
$bkrSearch = $searchForBKR . ' like "%';
$hypotechSearch = $searchForHypotech . ' like "%';
$searchCompany = $searchCompanyFor . ' like "%';
$searchPlaintiff = $searchPlaintiffFor . ' like "%';
$searchDefendantName = $searchDefendantNameFor . ' like "%';
$search = $search . $arraySearch[0] . '%"';
$bkrSearch = $bkrSearch . $arraySearch[0] . '%"';
$hypotechSearch = $hypotechSearch . $arraySearch[0] . '%"';
$searchCompany = $searchCompany . $arraySearch[0] . '%"';
$searchPlaintiff = $searchPlaintiff . $arraySearch[0] . '%"';
$searchDefendantName = $searchDefendantName . $arraySearch[0] . '%"';
for ($i = 1; $i < count($arraySearch); $i++) {
$search = $search . " or " . $searchFor . ' like "%' . $arraySearch[$i] . '%"';
$bkrSearch = $bkrSearch . " or " . $searchForBKR . ' like "%' . $arraySearch[$i] . '%"';
$hypotechSearch = $hypotechSearch . " or " . $searchForHypotech . ' like "%' . $arraySearch[$i] . '%"';
$searchCompany = $searchCompany . " or " . $searchCompanyFor . ' like "%' . $arraySearch[$i] . '%"';
$searchPlaintiff = $searchPlaintiff . " or " . $searchPlaintiffFor . ' like "%' . $arraySearch[$i] . '%"';
$searchDefendantName = $searchDefendantName . " or " . $searchDefendantNameFor . ' like "%' . $arraySearch[$i] . '%"';
}
$sis = DB::select('select debtor_name, count(*) as sis_total from equifax_sis_regions' . $search . ')
group by debtor_name');
$bkr = DB::select('select estate_name as debtor_name, count(*) as bkr_total from equifax_bkr_regions' . $bkrSearch . ')
group by estate_name');
$hypotech = DB::select('select hypleg_lot_credit_debtor_name as debtor_name, count(*) as hypotech_total from equifax_hypotech_regions' . $hypotechSearch . ')
group by hypleg_lot_credit_debtor_name');
I have tried replacing the 3 queries by using outer joins like this:
$other = 'select debtor_name, count(debtor_name) as sis_total,
estate_name as debtor_name, count(estate_name) as bkr_total
hypleg_lot_credit_debtor_name as debtor_name, count(hypleg_lot_credit_debtor_name) as hypotech_total
from equifax_sis_regions outer join equifax_bkr_regions on (equifax_sis_regions.debtor_name=estate_name)
outer join equifax_hypotech_regions on (equifax_sis_regions.debtor_name=hypleg_lot_credit_debtor_name)
WHERE (' . $search . ') OR ' . $bkrSearch . ') OR (' . $hypotechSearch . ')
GROUP BY debtor_name, estate_name, hypleg_lot_credit_debtor_name';
but that is a much slower query to run. The database contains over 4 million rows and the difference in API calls to the 2 query versions is ~53 seconds for the original and ~78 seconds for the combined form. Is there any way I can modify this combined query to be faster rather than slower?
Thanks in advance
You can use the UNION ALL operator to combine multiple SELECT statements. You could combine them like this:
SELECT debtor_name, SUM(sis_total), SUM(bkr_total), SUM(hypotech_total)
FROM (
SELECT debtor_name, COUNT(*) AS sis_total, 0 AS bkr_total, 0 AS hypotech_total
FROM equifax_sis_regions
-- add where clause here
GROUP BY debtor_name
UNION ALL
SELECT estate_name AS debtor_name, 0 AS sis_total, COUNT(*) AS bkr_total, 0 AS hypotech_total
FROM equifax_bkr_regions
-- add where clause here
GROUP BY estate_name
UNION ALL
SELECT hypleg_lot_credit_debtor_name AS debtor_name, 0 AS sis_total, 0 AS bkr_total, COUNT(*) AS hypotech_total
FROM equifax_hypotech_regions
-- add where clause here
GROUP BY hypleg_lot_credit_debtor_name
) derived
GROUP BY debtor_name;

single instead of double select statement

first table - bplus - has a column named home01 with values identical to some values in column fname of table banners
$items = '';
$sql = "select home01 from bplus";
$st = $db->query($sql);
$arr = $st->fetchAll(PDO::FETCH_COLUMN);
foreach ($arr as $el){
$el = trim($el);
$sqlb = "select * from banners where fname = '" . $el . "'";
$stb = $db->query($sqlb);
$row = $stb->fetch();
$items .= "<img class='itemtop' src = '../banners/" . $el . "' alt='img' data-id = " . $row['id'] . " data-fname = '" . $row['fname'] . ">\n";
}
echo $items;
this works but probably there is a shorter way, with a single select statement.
Any help?
use LEFT JOIN
select bplus.home01, banners.* from bplus left join banners on bplus.home01 = banners.fname;

Retrieve data from three table using join in CodeIgniter

I am trying to get result from three table using CodeIgnitor active record. But I am just getting record who match with second join condition only. But I need all record..
$uid = $this->session->userdata('uid');
$codn = ['stud.uid'=>$uid,'stud.status'=>"ACTIVE"];
$liststudent = $this->db->select('stud.id,stud.studname,stud.mobile1,stud.photo,stud.totalfees,bs.title,SUM(sp.pay_in_digit) AS paidfees')
->from('students as stud')
->join('batchsetting as bs', 'bs.id = stud.bid')
->join('stud_payment as sp', 'sp.sid = stud.id')
->where($codn)
->get();
return $liststudent->result();
Here is the my query.
Concept is: I need batch title from batchsetting who's 'id = stud.bid'. and sum of paidfees from stud_payment who's 'sid=stud.id'.
But in result I am getting only those record of student who's record avail in stud_payment table.
Table students has not any field named as bid.So
Change
->join('batchsetting as bs', 'bs.id = stud.bid')
to
->join('batchsetting as bs', 'bs.id = stud.id')
Try using below code
$uid = $this->session->userdata('uid');
$liststudent = $this->db->select('stud.id,stud.studname,stud.mobile1,stud.photo,stud.totalfees,bs.title,SUM(sp.pay_in_digit) AS paidfees')
->from('students as stud')
->join('batchsetting as bs', 'bs.id = stud.id')
->join('stud_payment as sp', 'sp.sid = stud.id')
->where('stud.uid',$uid)
->where('stud.status',"ACTIVE");
return $liststudent->result();
Try to use a left join in your jointure. Code below :
$uid = $this->session->userdata('uid');
$codn = ['stud.uid'=>$uid,'stud.status'=>"ACTIVE"];
$liststudent = $this->db->select('stud.id,stud.studname,stud.mobile1,stud.photo,stud.totalfees,bs.title,SUM(sp.pay_in_digit) AS paidfees')
->from('students as stud')
->join('batchsetting as bs', 'bs.id = stud.bid', 'left')
->join('stud_payment as sp', 'sp.sid = stud.id', 'left')
->where($codn)
->get();
return $liststudent->result();
Basically ci bydefault consider inner Join query.so you need to specify left join
->join('stud_payment as sp', 'sp.sid = stud.id', 'left');
Use full outer join.
function full_outer_join() {
$sql = 'SELECT ' . $this->blogs . '.blog_id,comment_id,blog_title,blog_content,blog_date,comment_text,comment_date
FROM ' . $this->blogs . ' LEFT OUTER JOIN ' . $this->blog_comments . ' ON ' . $this->blog_comments . '.blog_id = ' . $this->blogs . '.blog_id
UNION
SELECT ' . $this->blogs . '.blog_id,comment_id,blog_title,blog_content,blog_date,comment_text,comment_date
FROM ' . $this->blogs . ' RIGHT OUTER JOIN ' . $this->blog_comments . ' ON ' . $this->blog_comments . '.blog_id = ' . $this->blogs . '.blog_id';
$query = $this->db->query($sql);
return $query->result();
}

Displaying Expenses under each expense type using MySQL PDO

I have two tables that I am creating a list that shows all the expenses under each expense type. I have been able to get it to work except when I add the
AND WHERE expenses.pid = " . $pid
it cases a Syntax error and I can't figure out way.
The biggest thing is I need to limet the Expense Type to only show the ones that have some data to go below them
EXPENSETYPE
typeid
pid
exptype
EXPENSES
expid
pid
expdate
checktype
payee
typeid
details
amount
<?php
$pid = 6;
$sql = "SELECT expensetype.typeid, expensetype.exptype
FROM `expensetype` WHERE expensetype.pid = $pid
ORDER BY expensetype.typeid DESC";
$expensetype = $db->query($sql);
foreach($expensetype as $type) {
echo '<li>' . $type['exptype'] . '<ul>';
$sql2 = "SELECT expenses.expid, expenses.expdate, expenses.checktype, expenses.payee, expenses.details, expenses.amount
FROM `expenses` WHERE `expenses`.typeid = " . $type['typeid'] . "AND WHERE expenses.pid = " . $pid ;
$expenses = $db->query($sql2);
foreach($expenses as $exp) {
echo '<li>' . $exp['expdate'] . ' ' . $exp['checktype'] . ' ' . $exp['expdate'] . ' ' . $exp['payee'] . ' ' . $exp['details'] .' ' . $exp['amount'] .'</li>';
}
echo '</ul></li>';
}
?>
Try this SQL statement instead of making two of them :
SELECT `expensetype`.`typeid`, `expensetype.exptype`, `expenses`.`expid`,
`expenses`.`expdate`, `expenses`.`checktype`, `expenses`.`payee`,
`expenses`.`details`, `expenses`.`amount`
FROM `expensetype` INNER JOIN `expenses` ON
`expensetype`.`typeid` = `expense`.`typeid`
WHERE (...)
Also, you cannot use two WHERE in a SQL statement, only use AND.

Entering my WHERE into the query breaks it

So I have to add a WHERE query to this plugin I'm using for a reporting feature on a WordPress site. I have no time to do anything but add in another column and filter by the values in that column as there is not that much data to manage each update. The default value for the column I added is zero but I'll add new entries to represent years new people are added. However, when I filter based on the column value the whole query breaks and doesn't show up. I have no idea why. Here is the section involving its set up query displaying results.
<?php
$sql = "SELECT COUNT(*) FROM " . $wpdb->prefix . "presidentsreport_breakdown WHERE list_id = " . $atts['list_id'];
$total_breakdowns = $wpdb->get_var($sql);
$sql = "SELECT p.person_id, p.name, p.notes, p.school_year, b.breakdown_id, b.name as breakdown, b.description as breakdown_description FROM " . $wpdb->prefix . "presidentsreport_person p INNER JOIN " . $wpdb->prefix . "presidentsreport_breakdown b ON b.breakdown_id = p.breakdown_id INNER JOIN " . $wpdb->prefix . "presidentsreport_list l ON l.list_id = b.list_id";
$clean_where = " WHERE l.list_id = " . $atts['list_id'];
$where = "";
if($search != ''){
$where = " AND (p.name LIKE %s)";
$arg = '%' . $search . '%';
$args = array($arg);
}
$where = $wpdb->prepare($where, $args);
$order = " ORDER BY b.sort_order, b.breakdown_id, p.sort_name, p.name, p.person_id";
$results = $wpdb->get_results($sql . $clean_where . $where . $order);
?>
If I add anything in the variable $where it breaks the whole query. So if I add
<?php
$where = " WHERE p.school_year <= 2011";
?>
or
<?php
$where = " WHERE p.school_year = 0";
?>
Nothing will show up, For the last example if the default value is 0 everything should show up regardless. Thanks in advance for reading through!
Don't add WHERE to your variable. It is already assigned in $clean_where
$clean_where = " WHERE l.list_id = " . $atts['list_id'];
Here ------------^
You need to concatenate your addition parameters to the $where variable:
$where .= " AND p.school_year <= 2011";
There's no need of WHERE in where!

Categories