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();
Related
I'm trying to make a "complex" (for me) querybuilder. Here is the basic SQL request:
SELECT DISTINCT fif.idfichefrais, fif.idvisiteur, fif.date, fif.nbjustificatifs, fif.montantvalide, fif.datemodif, fif.idetat, montantTotalFraisForfait, montantTotalFraisHorsForfait, libelleFraisHorsForfait
FROM FicheFrais fif
INNER JOIN (SELECT lff.idfichefrais, SUM(frf.montantFraisForfait*lff.quantite) as montantTotalFraisForfait
FROM LigneFraisForfait AS lff
INNER JOIN FraisForfait AS frf ON frf.idfraisforfait = lff.idfraisforfait
GROUP BY lff.idfichefrais) a USING (idfichefrais)
INNER JOIN (SELECT e.idetat, e.libelleEtat
FROM Etat AS e) b USING (idetat)
LEFT JOIN (SELECT lfhf.idfichefrais, SUM(lfhf.montant) as montantTotalFraisHorsForfait, lfhf.libelle as libelleFraisHorsForfait
FROM LigneFraisHorsForfait AS lfhf
GROUP BY lfhf.idfichefrais) c USING (idfichefrais)
WHERE fif.idvisiteur = '?'
AND YEAR(fif.date) ='?'
ORDER BY MONTH(fif.date) ASC;
and here is my querybuilder that I'm trying to accomplish
public function findFicheFraisByIdVisiteurAndAnnee($idvisiteur, $annee): array
{
$qb = $this->getEntityManager()->createQueryBuilder();
$a = $this->getEntityManager()->createQueryBuilder();
$b = $this->getEntityManager()->createQueryBuilder();
$c = $this->getEntityManager()->createQueryBuilder();
$selectFraisForfait = $a->select(array('lff.idfichefrais, SUM(frf.montantFraisForfait*lff.quantite)'))
->from('App:Lignefraisforfait', 'lff')
->innerJoin('App:Fraisforfait', 'frf', Join::WITH, 'frf.idfraisforfait = lff.idfraisforfait')
->groupBy('lff.idfichefrais');
$selectEtat = $b->select(array('e.idetat, e.libelleEtat ad libelleFraisHorsForfait'))
->from('App:Etat', 'e');
$selectFraisHorsForfait = $c->select(array('lfhf.idfichefrais, SUM(lfhf.montant) as montantTotalFraisHorsForfait'))
->from('App:Lignefraishorsforfait','lfhf')
->groupBy('lfhf.idfichefrais');
return $FicheFraisByIdVisiteurAndAnnee = $qb
->select(array('fif.idfichefrais, identity(fif.idvisiteur) as idvisiteur, fif.date, fif.nbjustificatifs, fif.montantvalide, fif.datemodif, identity(fif.idetat) as idetat,montantTotalFraisForfait, montantTotalFraisHorsForfait, libelleFraisHorsForfait'))
->from('App:Fichefrais', 'fif')
->innerJoin('App:Lignefraisforfait', sprintf('($s)selectfraisforfait', $selectFraisForfait->getDQL()), Join::WITH, 'fif.idfichefrais = selectfraisforfait.idfichesfrais')
->innerJoin('App:Etat', sprintf('($s)selectetat', $selectEtat->getDQL()), Join::WITH, 'fif.idetat = selectetat.idetat')
->leftJoin('App:Lignefraishorsforfait', sprintf('($s)selectFraisHorsForfait', $selectFraisHorsForfait->getDQL()), Join::WITH, 'fif.idfichefrais = selectfraishorsforfait.idfichefrais')
->where('fif.idvisiteur = :idvisiteur')
->setParameter('idvisiteur' , $idvisiteur)
->andWhere('YEAR(fif.date) = :annee')
->setParameter('annee', $annee)
->groupBy('fif.idfichefrais')
->groupBy('lfhf.idfichefrais')
->orderBy('MONTH(fif.date)', 'ASC')
->setMaxResults(12)
->getQuery()
->getResult()
;
}
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();
}
This is a search function that returns each member with their most recent year registered.
I got it working with a DB::raw() call. But can't get it working with the query builder.
Working Code:
$query = DB::table('membership as m');
$query->join(
DB::raw(
'(SELECT my.*
FROM membership_years my
INNER JOIN (
SELECT member_id,MAX(membership_year) AS max_my
FROM membership_years
GROUP BY member_id
) my2
ON my.member_id = my2.member_id
AND my.membership_year = my2.max_my
) my'
)
,'m.id','=','my.member_id');
My attempt on query builder code:
$query = DB::table('membership as m');
$query->join('membership_years as my',
function($j1){
$j1->join('membership_years as my2',
function($j2){
$j2->where('my.membership_year','=','MAX(my2.membership_year)')
->on('my.member_id','=','my2.member_id');
}
)->on('m.id','=','my.member_id');
}
);
The resulting error is:
Call to undefined method Illuminate\Database\Query\JoinClause::join()
I'm not sure if this is because the $j2 doesn't have access to the join method anymore?
Raw MySQL query:
SELECT my.membership_year,m.*
FROM membership AS m
INNER JOIN
(
SELECT my1.*
FROM membership_years my1
INNER JOIN
(
SELECT member_id,MAX(membership_year) AS max_my
FROM membership_years
GROUP BY member_id
) my2
ON my1.member_id = my2.member_id
AND my1.membership_year = my2.max_my
) my
ON m.id = my.member_id
ORDER BY m.id ASC
Way 1. You can write part of the query with builder:
$query = DB::table('membership as m')
->select('my.membership_year', 'm.*')
->join(DB::raw('(
SELECT my1.*
FROM membership_years my1
INNER JOIN (
SELECT member_id, MAX(membership_year) AS max_my
FROM membership_years
GROUP BY member_id
) my2
ON my1.member_id = my2.member_id
AND my1.membership_year = my2.max_my
) my'),
'm.id', '=', 'my.member_id')
->orderBy('m.id');
Way 2. Also you can write subqueries and use toSql() method:
$sub1 = DB::table('membership_years')
->select('member_id', DB::raw('MAX(membership_year) AS max_my'))
->groupBy('member_id');
$sub2 = DB::table('membership_years as my1')
->select('my1.*')
->join(DB::raw('(' . $sub1->toSql() . ') my2'),
function ($join) {
$join
->on('my1.member_id', '=', 'my2.member_id')
->on('my1.membership_year', '=', 'my2.max_my');
});
$query = DB::table('membership as m')
->select('my.membership_year', 'm.*')
->join(DB::raw('(' . $sub2->toSql() . ') my'), 'm.id', '=', 'my.member_id')
->orderBy('m.id');
How to do this query in Doctrine 2 QueryBuilder:
SELECT AVG(x.distance) avg_distance FROM (SELECT r.* FROM result r WHERE r.place_id = ? GROUP BY r.place_id ORDER BY r.id DESC LIMIT 100
I try this:
$dql = $qb
->select('r.*')
->from('CoreBundle:Result', 'r')
->where('r.place = :place')
->orderBy('r.id', 'DESC')
->setMaxResults(100)
->setParameter('place', $place)
->getDQL()
;
$result = $qb
->select('AVG(x.distance) avg_distance')
->from($dql, 'x')
->getQuery()
->getArrayResult();
but not work
SELECT r.* FROM': Error: Class 'SELECT' is not defined.
$sql = "SELECT AVG(x.distance) avg_distance FROM (SELECT r.* FROM result r WHERE r.place_id = :place_id ORDER BY r.id DESC LIMIT 100) x ";
$stmt = $this->em->getConnection()->prepare($sql);
$stmt->bindValue(':place_id', $place->getId());
$stmt->execute();
return $stmt->fetch();
I've read the Doctrine2 documentation about native sql queries.
It doesn't talk about entities joined by a ManyToMany relation.
I didn't figure how to handle that, any idea or example.
You just have to manually add the join table into the sql. Extending the example in chpt 14 of the Doctrine manual:
$rsm = new ResultSetMapping;
$rsm->addEntityResult('User', 'u');
$rsm->addFieldResult('u', 'id', 'id');
$rsm->addFieldResult('u', 'name', 'name');
$rsm->addJoinedEntityResult('Address' , 'a', 'u', 'address');
$rsm->addFieldResult('a', 'address_id', 'id');
$rsm->addFieldResult('a', 'street', 'street');
$rsm->addFieldResult('a', 'city', 'city');
$sql = 'SELECT u.id, u.name, a.id AS address_id, a.street, a.city FROM users u ' .
'INNER JOIN address__user j ON u.id = j.user '.
'INNER JOIN address a ON a.id = j.address '.
'WHERE u.name = ?';
$query = $this->_em->createNativeQuery($sql, $rsm);
$query->setParameter(1, 'romanb');
$users = $query->getResult();
This example assumes your join table has fields address and user for its keys.