Retrieve data from three table using join in CodeIgniter - php

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();
}

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;

Rewriting database query in Codeigniter's query builder

I'm trying to rewrite existing database query in Codeigniter' query builder, how do I solve WHERE EXISTS(I think that's where's the problem)?
This is original query I want to rewrite:
$query = $this->db->query('SELECT p_customer.*' .
' FROM p_customer' .
' WHERE EXISTS (' .
'SELECT null' .
' FROM p_customer_group_rel' .
' WHERE p_customer_group_rel.customer_group_id=' . $e_id.
' AND p_customer_group_rel.customer_id = p_customer.id' .
')' .
' AND p_customer.deleted IS NULL' .
' AND p_customer.id > 0' .
' ORDER BY p_customer.full_name'
);
This is what I got so far:
$query = $this->db
->select('p_customer.*')
->from('p_customer')
->where('EXISTS(SELECT null FROM p_customer_group_rel WHERE
p_customer_group_rel.customer_group_id= ' . $e_id . ' AND
p_customer_group_rel.customer_id = p_customer.id)')
->where('p_customer.deleted is NULL')
->where('p_customer.id > 0')
->order_by('p_customer.full_name');
->get();
The result I get from first query is array of object.
This is what I get from my query:
SELECT p_customer.* FROM p_customer WHERE EXISTS( SELECT null FROM p_customer_group_rel WHERE p_customer_group_rel.customer_group_id= $e_id ) AND p_customer_group.port_id = p_port.id
which is not what I want, any help? :)
Maybe it's not best solution, but I did the following and it works:
$sub_q = 'SELECT null FROM p_customer_group_rel WHERE p_customer_group_rel.customer_group_id=' . $e_id . ' AND p_customer_group_rel.customer_id = p_customer.id';
$query = $this->db ->select('p_customer.*') ->from('p_customer') ->where('EXISTS(' . $sub_q . ')') ->where('p_customer.id >', 0) ->where('p_customer.deleted', NULL) ->order_by('p_customer.full_name') ->get();

Wordpress query with variable in SQL

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.

Adapting query to JDatabase

How can I adapt the following query to JDatabase?
SELECT
c.RAZONSOCIAL usu_razonSocial
,c.NIT usu_nit
,c.SEDE usu_sede
,c.EMAIL usu_email
,IF(IFNULL(u.block, 1) = 0, 'Activo', 'Inactivo') usu_estado
,COUNT(ct.ctf_id) nroCertificados
FROM
cargacliente c
INNER JOIN
cargas
ON (crg_id = cargas_id)
AND (crg_status = 'Ok')
INNER JOIN
certificados ct
ON (ctf_sede = SEDE)
AND (ctf_nit = NIT)
LEFT JOIN
database_1.bml_users u
ON (id = user_id)
GROUP BY
c.NIT
,c.SEDE
ORDER BY
usu_razonSocial
,usu_nit
,usu_sede;
This is Joomla 2.5.4.
I have read this post but I couldn't do it.
I tried to do it in this way:
<?php
$query
->select($db->quoteName(array('c.RAZONSOCIAL AS usu_razonSocial', 'c.NIT usu_nit', 'c.SEDE usu_sede', 'c.EMAIL usu_email', 'IF(IFNULL(u.block, 1) = 0, \'Activo\', \'Inactivo\') usu_estado', 'COUNT(ct.ctf_id) nroCertificados')))
->from($db->quoteName('database_2.cargacliente', 'c'))
->join('INNER', $db->quoteName('database_2.cargas','a') . ' ON (' . $db->quoteName('a.crg_id') . ' = ' . $db->quoteName('database_2.cargacert.cargas_id') . ') AND (' . $db->quoteName('a.crg_status') . ' = \'Ok\')')
->join('INNER', $db->quoteName('database_2.certificados','b') . ' ON (' . $db->quoteName('b.ctf_sede') . ' = ' . $db->quoteName('database_2.cargacliente.SEDE') . ') AND (' . $db->quoteName('b.ctf_nit') . ' = NIT)')
->join('LEFT', $db->quoteName('joomla_database.bml_users', 'u') . ' ON (' . $db->quoteName('database_2.usuario.usu_id') . ' = ' . $db->quoteName('joomla_database.bml_users.user_id') . ')')
->group(array('c.NIT', 'c.SEDE'))
->order(array('database_2.usuario.usu_razonSocial', 'database_2.usuario.usu_nit', 'database_2.usuario.usu_sede'));
?>
The error shown is the following:
500 - Ha ocurrido un error.
Unknown column 'c.RAZONSOCIAL usu_razonSocial' in 'field list' SQL=SELECT `c`.`RAZONSOCIAL usu_razonSocial`,`c`.`NIT usu_nit`,`c`.`SEDE usu_sede`,`c`.`EMAIL usu_email`,`IF(IFNULL(u`.`block, 1) = 0, 'Activo', 'Inactivo') usu_estado`,`COUNT(ct`.`ctf_id) nroCertificados` FROM `biochemical`.`cargacliente` AS `c` INNER JOIN `biochemical`.`cargas` AS `a` ON (`a`.`crg_id` = `biochemical`.`cargacert`.`cargas_id`) AND (`a`.`crg_status` = 'Ok') INNER JOIN `biochemical`.`certificados` AS `b` ON (`b`.`ctf_sede` = `biochemical`.`cargacliente`.`SEDE`) AND (`b`.`ctf_nit` = NIT) LEFT JOIN `biochemical_bml`.`bml_users` AS `u` ON (`biochemical`.`usuario`.`usu_id` = `biochemical_bml`.`bml_users`.`user_id`) GROUP BY c.NIT,c.SEDE ORDER BY biochemical.usuario.usu_razonSocial,biochemical.usuario.usu_nit,biochemical.usuario.usu_sede
The changes were the following:
Remove the first $db->quoteName() in the SELECT statement.
Modify ALIAS from tables.
LEFT JOIN modification.
The final code is the following:
$query
->select(array('c.RAZONSOCIAL AS usu_razonSocial', 'c.NIT AS usu_nit', 'c.SEDE AS usu_sede', 'c.EMAIL AS usu_email', 'IF(IFNULL(u.block, 1) = 0, \'Activo\', \'Inactivo\') AS usu_estado', 'COUNT(b.ctf_id) AS nroCertificados'))
->from($db->quoteName('database_2.cargacliente', 'c'))
->join('INNER', $db->quoteName('database_2.cargas','a') . ' ON (' . $db->quoteName('a.crg_id') . ' = ' . $db->quoteName('c.cargas_id') . ') AND (' . $db->quoteName('a.crg_status') . ' = \'Ok\')')
->join('INNER', $db->quoteName('database_2.certificados','b') . ' ON (' . $db->quoteName('b.ctf_sede') . ' = ' . $db->quoteName('c.SEDE') . ') AND (' . $db->quoteName('b.ctf_nit') . ' = c.NIT)')
->join('LEFT', $db->quoteName('joomla_database.bml_users', 'u') . ' ON (' . $db->quoteName('c.user_id') . ' = ' . $db->quoteName('u.id') . ')')
->group(array('c.NIT', 'c.SEDE'))
->order(array('usu_razonSocial', 'usu_nit', 'usu_sede'));
This is a bit difficult to say what the problem is without having the right environment.
I would suggest to debug through the driver to see where it fails.
You can of course also put the query direct through the "setQuery" method. It would be however compatible with MySQL only.
But, once again, please update your Joomla! to the latest version ASAP.

how to get all attributes in prestashop

I need to get all attributes that exists in my Prestahop store not matter wich or what product is assigned I just want to generate a array of those attributes and then use them in ProductController.php class. I check the file classes/Product.php and a method called getDefaultAttribute($id_product, $minimumQuantity = 0) is present but I think this only works for attributes assigned to a specific product and not return all as I need. Any help? I'm newbie with Prestashop and need to learn a lot of things
Examine file classes/Attribute.php. Your may use static function Attribute::getAttributes($id_lang, $not_null = false). It return all attributes for a given language.
You can get all attributes by using this SQL query:
$atbt = "SELECT a.id_attribute_group , a.name
FROM " . _DB_PREFIX_ . "attribute_group_lang a
where id_lang='".$id_lang."'";
$res = Db::getInstance()->ExecuteS($atbt);
$product_result = array();
$i=0;
foreach ($res as $key => $row) {
$sql = 'SELECT pal.name AS label,pal.id_attribute AS value,0 AS status'
. ' FROM ' . _DB_PREFIX_ . 'attribute AS pa
RIGHT JOIN ' . _DB_PREFIX_ . 'attribute_group_lang AS pagl ON (pagl.id_attribute_group =pa.id_attribute_group)
LEFT JOIN ' . _DB_PREFIX_ . 'attribute_lang AS pal ON (pal.id_attribute =pa.id_attribute)
JOIN ' . _DB_PREFIX_ . 'product_attribute_combination AS pacl ON (pacl.id_attribute =pal.id_attribute)
JOIN ' . _DB_PREFIX_ . 'product_attribute AS pat ON (pat.id_product_attribute =pacl.id_product_attribute)
JOIN ' . _DB_PREFIX_ . 'product AS prot ON (prot.id_product =pat.id_product)
WHERE pagl.id_lang="'.$id_lang.'" AND pal.id_lang="'.$id_lang.'" AND pagl.id_attribute_group=' . $row['id_attribute_group'].' AND prot.id_category_default = "'.$id_category.'" GROUP BY pacl.id_attribute';
$result = Db::getInstance()->ExecuteS($sql);
}

Categories