concat in condition left join active record codeigniter - php

I have a problem with active record codeigniter ver 2 wih special criteria like this:
$this->db->select('t_po_detail_item, t_process_shif, m_machine_lines, m_machine_mac, t_po_detail_no,
t_prod_lot, CONCAT(t_prod_lot, "-", t_prod_sublot) AS nolot,
COUNT(t_prod_sublot) AS qtybox, SUM(t_process_qty) AS qtypcs,
ROUND((SUM(t_process_qty)*m_process_weight)/1000,1) AS qtyberat', FALSE);
$this->db->join(self::$table2, 't_process_prod_id = t_prod_id', 'left')
->join(self::$table3, 't_prod_lot = t_po_detail_lot_no', 'left')
->join(self::$table5, 't_process_machine = m_machine_id', 'left')
->join(self::$table4, 'CONCAT_WS("-",t_po_detail_item, t_process_cat) = CONCAT_WS("-",m_process_id, m_process_proc_cat_id)', 'left');
$this->db->where('t_process_cat', 16);
$this->db->group_by('nolot');
$query = $this->db->get(self::$table1);
there are have special criteria join condition with concat WS. If i use standard query mysql, the query is running ok.
$sql = 'SELECT t_po_detail_item, t_process_shif, m_machine_lines, m_machine_mac, t_po_detail_no, t_prod_lot, CONCAT_WS("-",t_prod_lot, t_prod_sublot) AS nolot,
COUNT(t_prod_sublot) AS qtybox, SUM(t_process_qty) AS qtypcs, ROUND((SUM(t_process_qty)*m_process_weight)/1000,1) AS qtyberat
FROM `t_process`
LEFT JOIN t_prod ON t_process_prod_id = t_prod_id
LEFT JOIN t_po_detail ON t_prod_lot = t_po_detail_lot_no
LEFT JOIN m_machine ON t_process_machine = m_machine_id
LEFT JOIN m_process ON CONCAT_WS("-",t_po_detail_item, t_process_cat) = CONCAT_WS("-",m_process_id, m_process_proc_cat_id)
WHERE t_process_cat=16
GROUP BY(nolot)';
$query = $this->db->query($sql);
There are wrong in my active record code ?
regards,
Neos.

When using MySQL functions inside Codeigniter query builder, you need functions to be outside quotes "", so you need to pass an optional fourth parameter to join, which says rather to escape the inputs or not, and your query becomes,
$this->db->join($table, $condition, $join_type, false);
Read more here: CI Docs - Query Builder

Related

What's wrong with this query in active record CodeIgniter 2?

I have some problem with active record in CodeIgniter 2.
SQL works perfectly:
SELECT c.title
, c.post_status
, d.data
FROM content c
JOIN content_fields_data d
ON c.id = d.item_id
WHERE c.full_tpl = 'page_doctor'
AND d.field_name = 'field_docid'
But when I'll try write this query in active record style, like this:
$this->db->select('c.title, c.post_status','cd.data', false);
$this->db->from('content as c');
$this->db->join('content_fields_data as cd', 'c.id = cd.item_id','left');
$this->db->where('c.full_tpl', 'page_doctor');
$this->db->where('cd.field_name', 'field_docid');
$allDatas = $this->db->get()->result_array();
I don't see in output cd.data.
What's I'm doing wrong?
By accident you split your list of columns to two method's arguments, it should be one string
$this->db->select('c.title, c.post_status, cd.data', false);

Yii2 translating findBySql query to QueryBuilder query

I have the following query using findbysql:
$query = Users::findBySql('select a.user_id, a.last_name,a.first_name, a.emp_id, ar.role_id from auth_users a, auth_user_roles AR, AUTH_USER_DEPTS AD, DEPARTMENTS D
where AD.DEPT_ID = D.DEPT_ID AND AR.USER_ID = AD.USER_ID and a.user_id = ar.user_id
AND D.DEPT_GROUP_ID = :dept_group_id AND (ACCESS_END_DATE > SYSDATE OR ACCESS_END_DATE IS NULL)
UNION
SELECT DISTINCT a.user_id, a.last_name, a.first_name, a.emp_id, NULL AS role_id FROM auth_users a, AUTH_USER_ROLES AR, AUTH_USER_DEPTS AD, DEPARTMENTS D
WHERE AD.DEPT_ID = D.DEPT_ID AND AR.USER_ID = AD.USER_ID and a.user_id = ar.user_id
AND D.DEPT_GROUP_ID = :dept_group_id AND
AR.ACCESS_END_DATE < SYSDATE AND AR.USER_ID NOT IN (select USER_ID from auth_user_roles where ACCESS_END_DATE > SYSDATE OR ACCESS_END_DATE IS NULL)', [':dept_group_id' => $dept_group_id ]);
This query does exactly what I want it to, but the problem is when I try to put it into a gridview it does not sort. According to Sort and search column when I'm querying with findbysql in yii2 it seems like I need to use query builder instead.
So I was trying to do that with the first part of my query (before the union), and it looks like so:
$query1 = (new \yii\db\Query())
->select(['user_id', 'last_name', 'first_name', 'emp_id'])
->from('AUTH_USERS');
$query2 = (new \yii\db\Query())
->select('USER_ID')
->from('AUTH_USER_ROLES')
->where('ACCESS_END_DATE>SYSDATE OR ACCESS_END_DATE IS NULL');
$query = $query1->innerJoin('AUTH_USER_DEPTS', 'AUTH_USER_DEPTS.user_id = AUTH_USERS.user_id')->innerJoin('DEPARTMENTS', 'AUTH_USER_DEPTS.dept_id = DEPARTMENTS.dept_id');
$query->innerJoin('AUTH_USER_ROLES', 'AUTH_USER_ROLES.USER_ID = auth_users.USER_ID')->where('ACCESS_END_DATE>SYSDATE OR ACCESS_END_DATE IS NULL');
However, my query comes out like this in yii and apparently oracle is not accepting the double quotes around the column names:
SELECT "user_id", "last_name", "first_name", "emp_id" FROM "AUTH_USERS"
INNER JOIN "AUTH_USER_DEPTS" ON AUTH_USER_DEPTS.user_id = AUTH_USERS.user_id
INNER JOIN "DEPARTMENTS" ON AUTH_USER_DEPTS.dept_id = DEPARTMENTS.dept_id
INNER JOIN "AUTH_USER_ROLES" ON AUTH_USER_ROLES.USER_ID = auth_users.USER_ID
WHERE ACCESS_END_DATE>SYSDATE OR ACCESS_END_DATE IS NULL
I know the query might be incorrect here already but I cant even get the double quotes to go away. Tried defining the select statements multiple ways suggested by the yii docs already with no success:
select(['user_id', 'last_name', 'first_name', 'emp_id'])
select('user_id', 'last_name', 'first_name', 'emp_id')
select("user_id, last_name,first_name,emp_id")
I have also tried joining the queries like this from the docs: http://www.yiiframework.com/doc-2.0/guide-db-query-builder.html
$query = $query1->innerJoin(['u' => $query2], 'u.user_id = user_id');
but it also complains that it doesnèt recognize u and the query instead comes out like so in yii:
SELECT COUNT(*) FROM "AUTH_USERS" INNER JOIN "AUTH_USER_DEPTS" ON AUTH_USER_DEPTS.user_id = AUTH_USERS.user_id INNER JOIN "DEPARTMENTS" ON AUTH_USER_DEPTS.dept_id = DEPARTMENTS.dept_id INNER JOIN (SELECT "USER_ID" FROM "AUTH_USER_ROLES" WHERE ACCESS_END_DATE>SYSDATE OR ACCESS_END_DATE IS NULL) "u" ON u.user_id = auth_users.user_id
At this point im just looking for the easiest way to build this query (whether it be using querybuilder or some other way) so that I can pass the query to my gridview and sort it.
I would recommend you first create all the data models you need from the tables you need for the query, using Gii it should be easy and it even creates the relationships you will need.
After that, you can do something like the following:
$query = Users::find()
->joinWith('theRelation1Name')
->joinWith('theRelation2Name')
->joinWith('theRelation3Name')
...
This way you don't need to give tables aliases or add the conditions needed for the relations to work.

How would I write this query that includes joins in CodeIgniter's query builder?

The query I'm trying to write is
SELECT Equipment.Name, Equipment.EquipmentTag, LoanedOut.StudentNumber, LoanedOut.DueDate
FROM Equipment, LoanedOut
WHERE Equipment.EquipmentRecordID = LoanedOut.EquipmentRecordID AND LoanedOut.StudentNumber = 040828055
I can't figure out how to do it using the query builder for codeigniter, the best I have so far is
$this->db->select('Equipment.Name, Equipment.EquipmentTag, LoanedOut.StudentNumber, LoanedOut.DueDate');
$this->db->from('Equipment e, LoanedOut l');
$this->db->join('l', 'e.EquipmentRecordID = l.EquipmentRecordID')->join('l', 'l.StudentNumber', $studentNumber);
This will give you what you want//
$sql = 'SELECT e.Name,e.EquipmentTag,l.StudentNumber,l.DueDate FROM Equipment e LEFT JOIN LoanedOut l ON e.EquipmentRecordID = l.EquipmentRecordID WHERE l.StudentNumber = "040828055"'
$query = $this->db->query($sql);

MySQL Query equivalent in CodeIgniter

MySQL Query is below
select PB.*, P.*, WhoCreated.*, WhoPlacedBid.* from tblprojectbid PB
Inner Join tblproject P on P.projectid = PB.projectid
Inner Join tbluser WhoCreated WhoCreated.UserID = P.WhoCreated
Inner Join tbluser WhoPlacedBid WhoPlacedBid.UserID = PB.WhoCreated
Where PB.FreelancerAwardedProjectStatusID in (4, 5)
and WhoCreated.UserID = 3
and PB.Reviewgiven = 0
Below is the query written in CodeIgnitor.
$this->_ci->db->select('PB.*, P.*, WhoCreated.*, WhoPlacedBid.*');
$this->_ci->db->from('tblprojectbid PB');
$this->_ci->db->join('tblproject P', 'P.projectid = PB.projectid');
$this->_ci->db->join('tbluser WhoCreated', 'WhoCreated.UserID = P.WhoCreated');
$this->_ci->db->join('tbluser WhoPlacedBid', 'WhoPlacedBid.UserID = PB.WhoCreated');
$this->_ci->db->or_where('PB.FreelancerAwardedProjectStatusID', 4);
$this->_ci->db->or_where('PB.FreelancerAwardedProjectStatusID', 5);
$this->_ci->db->where('WhoCreated.UserID', 5);
$this->_ci->db->where('PB.Reviewgiven', 5);
$query = $this->_ci->db->get();
Can you please help in correcting the above query to make it equivalant to MYSQL query above ?
$this->db->select() accepts an optional second parameter. If you set it to FALSE, CodeIgniter will not try to protect your field or table names with backticks. You don't need to repeat $this->_ci->db-> untill you don't want to add join or conditions with a conditional statement. Use where_in() for checking the same column name with more than one value . And you can optimize the code like this:
$this->_ci->db->select('PB.*, P.*, WhoCreated.*, WhoPlacedBid.*',FALSE)
->from('tblprojectbid PB')
->join('tblproject P', 'P.projectid = PB.projectid')
->join('tbluser WhoCreated', 'WhoCreated.UserID = P.WhoCreated')
->join('tbluser WhoPlacedBid', 'WhoPlacedBid.UserID = PB.WhoCreated')
->where_in('PB.FreelancerAwardedProjectStatusID', array(4,5))
->where(array('WhoCreated.UserID' => 5, 'PB.Reviewgiven' => 5))
->get();
Little corrections:
1) add second parameter false to select() to avoid backticks.
2) used where_in
$this->_ci->db->select('PB.*, P.*, WhoCreated.*, WhoPlacedBid.*',false);
$this->_ci->db->from('tblprojectbid PB');
$this->_ci->db->join('tblproject P', 'P.projectid = PB.projectid');
$this->_ci->db->join('tbluser WhoCreated', 'WhoCreated.UserID = P.WhoCreated');
$this->_ci->db->join('tbluser WhoPlacedBid', 'WhoPlacedBid.UserID = PB.WhoCreated');
$this->_ci->db->where_in('PB.FreelancerAwardedProjectStatusID', array(4,5));
$this->_ci->db->where('WhoCreated.UserID', 5);
$this->_ci->db->where('PB.Reviewgiven', 5);
$query = $this->_ci->db->get();
let me know if it's working.

Codeigniter join query multiple conditions don't work

I want to select data from my database table with join query, but my it doesn't work.
My query:
$this->db->select();
$this->db->from('we');
$this->db->join('schedule', 'schedule.itemid = we.cid');
$this->db->join('schedule', 'schedule.itemtype = 'testitem'');
$this->db->where('we.isActive','Y');
This line makes problem with schedule.itemtype = 'testitem':
$this->db->join('schedule', 'schedule.itemtype = 'testitem'');
How can I solve this?
You don't need to join same table twice.
But just to extend ON clause:
$this->db->select();
$this->db->from('we');
$this->db->join('schedule', 'schedule.itemid = we.cid AND schedule.itemtype = \'testitem\'');
$this->db->where('we.isActive','Y');
try
$this->db->select();
$this->db->from("we");
$this->db->join("schedule", "schedule.itemid = we.cid");
$this->db->where("schedule.itemtype","testitem");
$this->db->where("we.isActive","Y");
I believe there are two problems here. The first problem is that you are using one too many quotes in the second join line in your query:
You have: $this->db->join('schedule', 'schedule.itemtype='testitem''); < extra quote
It should be: $this->db->join('schedule', 'schedule.itemtype=testitem');
Second problem: your join doesnt make sense.
Your statement:
$this->db->select();
$this->db->from('we');
$this->db->join('schedule', 'schedule.itemid = we.cid');
$this->db->join('schedule', 'schedule.itemtype = testitem');
$this->db->where('we.isActive','Y');
Translates to:
SELECT * FROM we
JOIN schedule ON schedule.itemid = we.cid
JOIN schedule ON schedule.itemtype = testitem
WHERE we.isActive = Y
As you can see you are joining the same table twice on different lines, not only that but what table does "testitem" belong to? We are left to assume that you perhaps want the join where itemtype = testitem which will mean this:
SELECT * FROM we
JOIN schedule ON schedule.itemid = we.cid
WHERE schedule.itemtype = testitem
AND we.isActive = Y
Therefore your final Codeigniter query should be:
$this->db->select('*');
$this->db->from('we');
$this->db->join('schedule', 'schedule.itemid = we.cid');
$this->db->where('schedule.itemtype', 'testitem');
$this->db->where('we.isActive','Y');
This will work:
$this->db->join('schedule', 'schedule.itemid = we.cid');
$this->db->where('we.isActive','Y');
$this->db->where('schedule.itemtype', 'testitem');
$this->db->get('we');
$this->db->query('select we_tbl.c_name from we we_tbl,schedule sch_tbl where sch_tbl.itemid = we_tbl.cid AND we_tbl.idActive = '.$activeData);
Try this query according to your problem this could get the data you need.
I've tested on different database but i tried to perform what you're trying to get. https://www.w3schools.com/sql/trysql.asp?filename=trysql_op_in
select
pro_tbl.ProductName,
cat_tbl.CategoryName ,
sup_tbl.SupplierName
from
Products pro_tbl,
Suppliers sup_tbl,
Categories cat_tbl
where
pro_tbl.SupplierID = sup_tbl.SupplierID AND
pro_tbl.CategoryID = cat_tbl.CategoryID;
Two possible problems, depending on what your desired outcome is:
If you need to make two joins and are getting an error with the second join clause, try using double quotes to enclose the constant value on the condition or you'll get a parse error:
$this->db->join('schedule', 'schedule.itemtype = "testitem"');
If you need to join only once with multiple conditions, use parentheses:
$this->db->select('*');
$this->db->from('we');
$this->db->join('schedule', '(schedule.itemid = we.cid AND schedule.itemtype="testitem")');
$this->db->where('we.isActive','Y');
You query is equivalent to writing:
select * from we
inner join schedule on schedule.itemid = we.cid
inner join schedule on schedule.itemtype = "testitem"
where we.isActive = 'Y'
but what you seem to need is
select * from we
inner join schedule on (schedule.itemid = we.cid AND schedule.itemtype = "testitem")
where we.isActive = 'Y'
On your original query, you are doing two joins. In the latter, you'll do only one with multiple conditions.

Categories