Changing sql query to yii2 format - php

Am using dataProvider and i would like to convert a query in sql so that it follows the dataProvider way of representing data
This is the raw sql
SELECT
tblpritems.PRlineID
, tblpritems.Tracking_Code
, tblpritems.Description
, tblpritems.Quantity
, tblpritems.Unit_Price
, tblpritems.Extended_price
, tblpritems.PRID
, tblpritems.pr_solicitation_id
, tblpritems.date_item_received
, tblpritems.Quantity_received
, tblpritems.Remarks_on_receipt
, tblpritems.Received_by
FROM
prts.tblpritems
INNER JOIN prts.tblpr
ON (tblpritems.PRID = tblpr.PRID)
INNER JOIN prts.tblprsolicitations
ON (tblprsolicitations.PRID = tblpr.PRID) AND (tblpritems.pr_solicitation_id = tblprsolicitations.pr_solicitation_id)
INNER JOIN prts.tblprsuppliers
ON (tblprsuppliers.pr_solicitation_id = tblprsolicitations.pr_solicitation_id)
INNER JOIN prts.tblpo
ON (tblpo.pr_supplier_id = tblprsuppliers.pr_supplier_id)
where tblpr.PRID=".$val." and tblpo.PO_Status_ID=7 and item_received_status=0
These are the relations i have in the tblpritems
public function getPR()
{
return $this->hasOne(Tblpr::className(), ['PRID' => 'PRID']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getPrSolicitation()
{
return $this->hasOne(Tblprsolicitations::className(), ['pr_solicitation_id' => 'pr_solicitation_id']);
}
Currently am using
$dataProvider = new SqlDataProvider([
'sql' => $sql,
'pagination' => [
'pageSize' => 10,
],
]);
But the problems is that i cant access $dataProvider->getAttributes() in sql dataProvider
I would like the sql code above to be in this format
$query = Tblprsuppliers::find()
->Joinwith('prSolicitation', 'prSolicitation.pr_solicitation_id = tblprsuppliers.pr_solicitation_id')
->Joinwith('supplier', 'supplier.supplier_id = tblprsuppliers.supplier_id')
->JoinWith('currency', 'currency.CurrencyID = tblprsuppliers.currency_id ');
How can i achieve this
This is the database schema

when you have complex sql related that return instance of model you can use findBySql this way
$sql = 'SELECT
tblpritems.PRlineID
, tblpritems.Tracking_Code
, tblpritems.Description
, tblpritems.Quantity
, tblpritems.Unit_Price
, tblpritems.Extended_price
, tblpritems.PRID
, tblpritems.pr_solicitation_id
, tblpritems.date_item_received
, tblpritems.Quantity_received
, tblpritems.Remarks_on_receipt
, tblpritems.Received_by
FROM
prts.tblpritems
INNER JOIN prts.tblpr
ON (tblpritems.PRID = tblpr.PRID)
INNER JOIN prts.tblprsolicitations
ON (tblprsolicitations.PRID = tblpr.PRID) AND (tblpritems.pr_solicitation_id = tblprsolicitations.pr_solicitation_id)
INNER JOIN prts.tblprsuppliers
ON (tblprsuppliers.pr_solicitation_id = tblprsolicitations.pr_solicitation_id)
INNER JOIN prts.tblpo
ON (tblpo.pr_supplier_id = tblprsuppliers.pr_supplier_id)
where tblpr.PRID=".$val." and tblpo.PO_Status_ID=7 and item_received_status=0';
$model = Pritems::findBySql($sql)->all();

Related

mysql query to check a field exist in an array in codeigniter

I post an array of skills from the form and i need to fetch list of candidates list related to the elements in array in codeigniter.
Controller
$data = array(
"mode" => $this->input->post("mode"),
"designation" => $this->input->post("designation"),
"notice_period" => $this->input->post("notice_period"),
"skill" => $this->input->post("skills"),
"cities" => $this->input->post("city")
);
$this->load->model("search_model");
$this->load->model("candidate_model");
$data["candidate"] = $this->search_model->fetch_candidate($data);
$data["designation"] = $this->candidate_model->fetch_designation();
$this->load->view('candidate_profiles', $data);
model
function fetch_candidate($data)
{
$mode = $data['mode'];
$designation = $data['designation'];
$notice_period = $data['notice_period'];
$skill = $data['skill'];
$skills = join(",",$skill);
$city = $data['cities'];
$query = $this->db->query("SELECT DISTINCT(U.user_id), U.firstname, U.lastname, U.username, U.usertype, U.email, U.phone, U.address, U.profile_image, C.name AS country,C.id AS countryid, S.name AS state,S.id AS stateid, A.housename, A.street, A.area, A.po, A.city, CJ.designation, CJ.resume, CJ.biography, CJ.hiring_mode, CJ.notice_period, CJ.current_CTC, CJ.expected_CTC, D.designation_id AS desig, D.designation AS desig_name
FROM users AS U
LEFT JOIN address AS A ON U.user_id=A.cand_id
LEFT JOIN cand_job_details AS CJ ON CJ.cand_id=U.user_id
LEFT JOIN designations AS D ON D.designation_id=CJ.designation
LEFT JOIN countries AS C ON C.id=A.country
LEFT JOIN states AS S ON S.id=A.state
LEFT JOIN user_skills AS US ON U.user_id=US.user_id
LEFT JOIN user_interested_cities AS UC ON U.user_id=UC.user_id
WHERE D.designation LIKE '$designation' && (CJ.hiring_mode='2' || CJ.hiring_mode='$mode') && CJ
.notice_period<='$notice_period' && UC.city='$city' && US.skill IN(".implode(",", $skills).")
");
return $query;
}
How to implement this on codeigniter?
Thanks in advance
You need try to add ' around each argument. After it should looks like IN ('PHP','AngularJS'), because it is a string value and datatype is varchar as well.
$skills = "'";
foreach($skill as $item) {
$skills .= $item."',";
}
$skills = trim($skills,",")
Codeigniter comes with a built in Querybuilder - i strongly suggest to use it, because it makes your life much easier, and protects you against SQL injections - which is clearly a problem in your case.
Try the following
function fetch_candidate($data)
{
$this->db
->select('SELECT DISTINCT(U.user_id), U.firstname, U.lastname, U.username, U.usertype, U.email, U.phone, U.address, U.profile_image, C.name AS country,C.id AS countryid, S.name AS state,S.id AS stateid, A.housename, A.street, A.area, A.po, A.city, CJ.designation, CJ.resume, CJ.biography, CJ.hiring_mode, CJ.notice_period, CJ.current_CTC, CJ.expected_CTC, D.designation_id AS desig, D.designation AS desig_name')
->from('users U')
->join('address A', 'U.user_id=A.cand_id', 'left')
->join('cand_job_details CJ', 'CJ.cand_id=U.user_id', 'left')
->join('designations D', 'D.designation_id=CJ.designation', 'left')
->join('countries C', 'C.id=A.country', 'left')
->join('states S', 'S.id=A.state', 'left')
->join('user_skills US', 'U.user_id=US.user_id', 'left')
->join('user_interested_cities UC', 'U.user_id=UC.user_id', 'left');
if (isset($data['designation']) && !empty($data['designation']))
{
$this->db->like('D.designation', $data['designation']);
}
if (isset($data['mode']) && !empty($data['mode']))
{
$this->db
->group_start()
->where('CJ.hiring_mode', 2)
->or_where('CJ.hiring_mode', $data['mode'])
->group_end();
}
if (isset($data['notice_period']) && !empty($data['notice_period']))
{
$this->db->where('CJ.notice_period <=', $data['notice_period']);
}
if (isset($data['city']) && !empty($data['city']))
{
$this->db->where('UC.city', $data['city']);
}
if (isset($data['skills']) && is_array($data['skills']))
{
$this->db->where_in('US.skill', $data['skills']);
}
return $this->db->get();
}

I'm getting an error when I send multiple tables to query with codeigniter active records

I tried to add all the tables to the private variable $table so that it returns them after the query but it gives me an error. The error is that it tells me that the table that I put does not exist.
OK so I have:
<?php
class Joins_model extends CI_Model{
private $table = 'cm_proveedor, cm_compras, cm_valuacion, cm_valuacionr, cm_nomina, cm_empleado';
function _construc(){
parent::Model();
}
function get_reg($data){
$this->db->select('
cm_proveedor.nombre,
cm_valuacion.mano_obra,
cm_valuacion.refaccion,
cm_valuacionr.refaccion,
cm_valuacion.costoHojalateria,
cm_valuacion.costoPintura,
cm_valuacion.costoMecanica,
cm_valuacion.pv_hojalateria,
cm_valuacion.pv_pintura,
cm_valuacion.pv_mecanica,
cm_valuacion.pc_hojalateria,
cm_valuacion.pc_pintura,
cm_valuacion.pc_mecanica,
cm_valuacion.tipo,
cm_valuacion.hojalateria,
cm_valuacion.pintura,
cm_valuacion.mecanica,
cm_valuacion.tipo_r,
cm_empleado.nombre,
cm_compras.precio
');
$this->db->from('
cm_proveedor
INNER JOIN cm_compras
ON cm_proveedor.id = cm_compras.id_proveedor
INNER JOIN cm_valuacion
ON cm_compras.id_siniestro = cm_valuacion.id_siniestro
INNER JOIN cm_valuacionr
ON cm_valuacion.id_siniestro = cm_valuacionr.id_siniestro
INNER JOIN cm_nomina
ON cm_valuacionr.id_siniestro = cm_nomina.id_siniestro
INNER JOIN cm_empleado
ON cm_nomina.id_empleado = cm_empleado.id
');
$this->db->where('cm_valuacion.id_siniestro',$data);
$this->db->order_by('id','asc');
return $this->db->get($this->table);
}
}
?>
and I'm getting the error:
Database error: A Database Error Occurred
Error Number: 1103
Incorrect table name 'cm_proveedor '
SELECT cm_proveedor.nombre, cm_valuacion.mano_obra, cm_valuacion.refaccion, cm_valuacionr.refaccion, cm_valuacion.costoHojalateria, cm_valuacion.costoPintura, cm_valuacion.costoMecanica, cm_valuacion.pv_hojalateria, cm_valuacion.pv_pintura, cm_valuacion.pv_mecanica, cm_valuacion.pc_hojalateria, cm_valuacion.pc_pintura, cm_valuacion.pc_mecanica, cm_valuacion.tipo, cm_valuacion.hojalateria, cm_valuacion.pintura, cm_valuacion.mecanica, cm_valuacion.tipo_r, cm_empleado.nombre, cm_compras.precio FROM (cm_proveedor INNER JOIN cm_compras ON cm_proveedor.id = cm_compras.id_proveedor INNER JOIN cm_valuacion ON cm_compras.id_siniestro = cm_valuacion.id_siniestro INNER JOIN cm_valuacionr ON cm_valuacion.id_siniestro = cm_valuacionr.id_siniestro INNER JOIN cm_nomina ON cm_valuacionr.id_siniestro = cm_nomina.id_siniestro INNER JOIN cm_empleado ON cm_nomina.id_empleado = cm_empleado.id, cm_proveedor, cm_compras, cm_valuacion, cm_valuacionr, cm_nomina, cm_empleado) WHERE cm_valuacion.id_siniestro = '6615' ORDER BY id asc
Filename: C:\xampp\htdocs\pits\system\database\DB_driver.php
Line Number: 330
Try this:
$this->db->select('
cm_proveedor.nombre,
cm_valuacion.mano_obra,
cm_valuacion.refaccion,
cm_valuacionr.refaccion,
cm_valuacion.costoHojalateria,
cm_valuacion.costoPintura,
cm_valuacion.costoMecanica,
cm_valuacion.pv_hojalateria,
cm_valuacion.pv_pintura,
cm_valuacion.pv_mecanica,
cm_valuacion.pc_hojalateria,
cm_valuacion.pc_pintura,
cm_valuacion.pc_mecanica,
cm_valuacion.tipo,
cm_valuacion.hojalateria,
cm_valuacion.pintura,
cm_valuacion.mecanica,
cm_valuacion.tipo_r,
cm_empleado.nombre,
cm_compras.precio
');
$this->db->from('cm_proveedor');
$this->db->join('cm_compras','cm_proveedor.id = cm_compras.id_proveedor');
$this->db->join('cm_valuacion','cm_compras.id_siniestro = cm_valuacion.id_siniestro');
$this->db->join('cm_valuacionr','cm_valuacion.id_siniestro = cm_valuacionr.id_siniestro');
$this->db->join('cm_nomina','cm_valuacionr.id_siniestro = cm_nomina.id_siniestro');
$this->db->join('cm_empleado','cm_nomina.id_empleado = cm_empleado.id');
$this->db->where('cm_valuacion.id_siniestro',$data);
$this->db->order_by('id','asc');
...

How to fix this query using Zend Framework2

I'm using ZendFramework2 and I need to make a custon query. I tried my query in mysql and it works perfectly.
SELECT p.idProyecto,p.nombre, e.nombre, e.apellido, sum(ar.tiempoEstimado)
estimado,DATE_FORMAT(p.fechaInicio, '%Y/%m/%d') as inicio,
DATE_FORMAT(p.fechaFin, '%Y/%m/%d') as fin, sum(r.tiempoRegistrado) as t_real
FROM Actividad as a
LEFT JOIN ActividadResponsable as ar
ON a.idActividad=ar.idActividad
and a.fechaInicio>="2014-10-13"
and a.fechaFin<="2014-10-19"
LEFT JOIN ActividadPlaneada as ap
On ap.idActividad = ar.idActividad
and ar.idActividad = a.idActividad
LEFT JOIN tipoActividad as ta
on ta.idTipoActividad= ap.idTipoActividad
LEFT JOIN proyecto as p
ON p.idProyecto=a.idProyecto
LEFT JOIN registro as r
ON a.idActividad=r.idActividad
and r.fechaRegistro>="2014-10-13 00:00:00"
and r.fechaRegistro<="2014-10-19 23:59:00"
LEFT JOIN empleado as e
ON p.creador = e.idEmpleado
GROUP BY a.idProyecto;
But when I code this into ZendFramework2 it changes this
LEFT JOIN ActividadResponsable as ar
ON a.idActividad=ar.idActividad
and a.fechaInicio>="2014-10-13"
and a.fechaFin<="2014-10-19"
So the result query that zend generates is
SELECT p.idProyecto, p.nombre, e.nombre, e.apellido, SUM(ar.tiempoEstimado) as estimado, p.fechaInicio as inicio, p.fechaFin as fin, sum(r.tiempoRegistrado) as t_real
FROM `Actividad`
LEFT JOIN `ActividadResponsable` AS `ar` ON `Actividad`.`idActividad`=`ar`.`idActividad`
LEFT JOIN `ActividadPlaneada` AS `ap` ON `ap`.`idActividad` = `ar`.`idActividad` and `ar`.`idActividad` = `Actividad`.`idActividad`
LEFT JOIN `TipoActividad` AS `ta` ON `ta`.`idTipoActividad`= `ap`.`idTipoActividad`
LEFT JOIN `Proyecto` AS `p` ON `p`.`idProyecto`=`Actividad`.`idProyecto`
LEFT JOIN `Registro` AS `r` ON `Actividad`.`idActividad`=`r`.`idActividad`
LEFT JOIN `Empleado` AS `e` ON `p`.`creador` = `e`.`idEmpleado`
WHERE `Actividad`.`fechaInicio` >= :where1 AND `Actividad`.`fechaFin` <= :where2 AND `r`.`fechaRegistro` >= :where3 AND `r`.`fechaRegistro` <= :where4
GROUP BY `Actividad`.`idProyecto`
The php code I have is this
$dbAdapterConfig = array(
'driver' => 'Pdo_Mysql',
'database' => '*',
'username' => '*',
'password' => '*',
'charset' => 'utf8'
);
$dbAdapter = new Adapter($dbAdapterConfig);
$sql = new Sql($dbAdapter);
$query = $sql->select();
$query->from('Actividad');
$query->columns(array(new \Zend\Db\Sql\Expression('p.idProyecto, p.nombre, e.nombre, e.apellido, SUM(ar.tiempoEstimado) as estimado, p.fechaInicio as inicio, p.fechaFin as fin, sum(r.tiempoRegistrado) as t_real')));
$query->join(array('ar' => 'ActividadResponsable'), 'Actividad.idActividad=ar.idActividad', array(), 'left');
$query->where->greaterThanOrEqualTo('Actividad.fechaInicio', $inicio);
$query->where->lessThanOrEqualTo('Actividad.fechaFin', $fin);
$query->join(array('ap' => 'ActividadPlaneada'), 'ap.idActividad = ar.idActividad and ar.idActividad = Actividad.idActividad', array(), 'left');
$query->join(array('ta' => 'TipoActividad'), 'ta.idTipoActividad= ap.idTipoActividad', array(), 'left');
$query->join(array('p' => 'Proyecto'), 'p.idProyecto=Actividad.idProyecto', array(), 'left');
$query->join(array('r' => 'Registro'), 'Actividad.idActividad=r.idActividad', array(), 'left');
$query->where->greaterThanOrEqualTo('r.fechaRegistro', "2014-10-13 00:00:00");
$query->where->lessThanOrEqualTo('r.fechaRegistro', "2014-10-19 23:59:00");
$query->join(array('e' => 'Empleado'), 'p.creador = e.idEmpleado', array(), 'left');
$query->group(array('Actividad.idProyecto'));
$statement = $sql->prepareStatementForSqlObject($query);
$result = $statement->execute();
$records = array();
foreach ($result as $return) {
$records[] = $return;
}
return $result;
the and's in the join query belongs to the joins on statement not the queries where statement , you need to add the on statement as a Expression like this :
$exp = new Expression('Actividad.idActividad=ar.idActividad and a.fechaInicio>=?
and a.fechaFin<=?',array($inicio,$fin));
$query->join(array('ar' => 'ActividadResponsable'), $exp , array(), 'left');

how to use join in yii

How to join using table model
model name:User
Query:
SELECT
DISTINCT (u.UserID),
u.usertypeid,
u.UserName
FROM user u, lkusergroup lug, `group` g
WHERE u.userid = lug.userid
AND g.groupid = lug.groupid
AND UserName = 'abcd';
Something like this but using model
$user = Yii::app()->db->createCommand()
->select('*')
->from('user u')
->join('lkusergroup lug', 'u.userid = lug.userid')
->join('group g', 'g.groupid = lug.groupid')
->where('UserName=:UserName', array(':UserName'=>$this->username))
->queryRow();

SQL query works on phpMyAdmin but not in Codeigniter

I have this query
SELECT
arl_kind,
IF (tof_art_lookup.arl_kind = 2, tof_suppliers.sup_brand, tof_brands.bra_brand) AS brand,
arl_display_nr
FROM
tof_art_lookup
LEFT JOIN
tof_brands
ON
bra_id = arl_bra_id
INNER JOIN
tof_articles
ON
tof_articles.art_id = tof_art_lookup.arl_art_id
INNER JOIN
tof_suppliers
ON
tof_suppliers.sup_id = tof_articles.art_sup_id
WHERE
arl_art_id = #art_id
AND arl_kind IN (3)
ORDER BY
arl_kind,
bra_brand,
arl_display_nr limit 100;
when I execute this on phpmyadmin or in any software that has sql comand capabilities everything works and the output is as i should.
The problem appears when I try to insert this in codeigniter, and my main probles is with the if statement, I tried to insert it like this
return $query = $this->db
->SELECT('
arl_kind,
IF (tof_art_lookup.arl_kind = 2, tof_suppliers.sup_brand, tof_brands.bra_brand) AS brand,
arl_display_nr
FROM
tof_art_lookup
LEFT JOIN
tof_brands
ON
bra_id = arl_bra_id
INNER JOIN
tof_articles
ON
tof_articles.art_id = tof_art_lookup.arl_art_id
INNER JOIN
tof_suppliers
ON
tof_suppliers.sup_id = tof_articles.art_sup_id
WHERE
arl_art_id = #art_id
AND arl_kind IN (3)
ORDER BY
arl_kind,
bra_brand,
arl_display_nr limit 100')
->get();
and second option like that
return $query = $this->db
->select('ARL_KIND, IF (tof_art_lookup.arl_kind = 2, tof_suppliers.sup_brand, tof_brands.bra_brand) AS brand,ARL_DISPLAY_NR')
->from('tof_art_lookup')
->join('tof_brands','bra_id = arl_bra_id','LEFT')
->join('tof_articles','tof_articles.art_id = tof_art_lookup.arl_art_id','INNER')
->join('tof_suppliers','tof_suppliers.sup_id = tof_articles.art_sup_id','INNER')
->where('ARL_ART_ID',$id)
->where_in('ARL_KIND',array('3'))
//->where('A.ARL_DISPLAY','0')
->group_by('arl_kind','bra_brand','arl_display_nr')
->get();
both of them work but partialy without the second select option the one with the if.
Can anyone help me to fix this.
I believe your code should look like this
return $query = $this->db
->select('arl_kind, IF(tof_art_lookup.arl_kind = 2, tof_suppliers.sup_brand, tof_brands.bra_brand) AS brand,ARL_DISPLAY_NR', FALSE)
->from('tof_art_lookup')
->join('tof_brands', 'bra_id = arl_bra_id', 'LEFT')
->join('tof_articles', 'tof_articles.art_id = tof_art_lookup.arl_art_id', 'INNER')
->join('tof_suppliers','tof_suppliers.sup_id = tof_articles.art_sup_id', 'INNER')
->where('arl_art_id', $id)
->where_in('arl_kind', array('3'))
->order_by('arl_kind','bra_brand','arl_display_nr')
->limit(100)
->get();
Note: second parameter of select() method is set to FALSE and order_by() is used instead of group_by() as in your original query.
use like this
$query_string = "SELECT
arl_kind,
IF (tof_art_lookup.arl_kind = 2, tof_suppliers.sup_brand, tof_brands.bra_brand) AS brand,
arl_display_nr
FROM
tof_art_lookup
LEFT JOIN
tof_brands
ON
bra_id = arl_bra_id
INNER JOIN
tof_articles
ON
tof_articles.art_id = tof_art_lookup.arl_art_id
INNER JOIN
tof_suppliers
ON
tof_suppliers.sup_id = tof_articles.art_sup_id
WHERE
arl_art_id = #art_id
AND arl_kind IN (3)
ORDER BY
arl_kind,
bra_brand,
arl_display_nr limit 100";
$query=$this->db->query($query_string);
if ($query->num_rows () > 0) {
return $query->result_array ();
} else {
return FALSE;
}

Categories