How to use "MAX" in codeigniter where? - mysql

There is $this->db_selec_max(); for select max element from row set in select but I want to use max in where. How to use "MAX" in codeigniter where? I want to convert following query in to codeigniter form
My query
SELECT rq_id, rq_plant_4sale_code, rq_serial_number, rq_quantity_requested, rq_requester_farm_id,
rq_fulfiller_farm_id, rqpri_description, rqrem_remark,rqrem_remark_datetime, rq_created_datetime,
plsal_name_botanical, plsal_name_english, pot_code, rqpri_description
FROM (reqn_requisitions)
LEFT JOIN reqn_requisition_priorities ON(rq_priority_rank=rqpri_rank)
LEFT JOIN reqn_requisition_remarks ON(rq_id=rqrem_reqn_id)
LEFT JOIN tukai_plants_4sale ON(rq_plant_4sale_code=plsal_id)
LEFT JOIN tukai_pots ON(plsal_pot_id=pot_id)
WHERE rqrem_remark_datetime IN(SELECT MAX(rqrem_remark_datetime) AS dt FROM reqn_requisition_remarks GROUP BY rqrem_reqn_id ) AND rq_challan_id=0'
I am trying like this
$this->db->select("rq_id, rq_plant_4sale_code, rq_serial_number, rq_quantity_requested, rq_requester_farm_id,
rq_fulfiller_farm_id, rqpri_description, rqrem_remark,rqrem_remark_datetime, rq_created_datetime,
plsal_name_botanical, plsal_name_english, pot_code, rqpri_description ");
$this->db->join('tukai_plants_4sale',
'tukai_plants_4sale.plsal_id = reqn_requisitions.rq_plant_4sale_code','left');
$this->db->join('tukai_pots',
'tukai_pots.pot_id = tukai_plants_4sale.plsal_pot_id','left');
$this->db->join('reqn_requisition_remarks',
'reqn_requisition_remarks.rqrem_reqn_id = reqn_requisitions.rq_id','left');
$this->db->order_by("rq_id","desc");

For complex where clause conditions you can use,
$this->db->where('<where condition here>', NULL, FALSE);
From docs:
$this->db->where() accepts an optional third parameter. If you set it to FALSE, CodeIgniter will not try to protect your field or table names with backticks.
Try below code:
/* Replace table_name with appropriate table names */
$this->db->select("table_name.rq_id, table_name.rq_plant_4sale_code, table_name.rq_serial_number, table_name.rq_quantity_requested, table_name.rq_requester_farm_id,
table_name.rq_fulfiller_farm_id, table_name.rqpri_description, rqrem_remark,table_name.rqrem_remark_datetime, table_name.rq_created_datetime,
table_name.plsal_name_botanical, table_name.plsal_name_english, table_name.pot_code, table_name.rqpri_description ");
$this->db->from('reqn_requisitions');
$this->db->join('reqn_requisition_priorities','reqn_requisitions.rq_priority_rank = reqn_requisition_priorities.rqpri_rank','left');
$this->db->join('reqn_requisition_remarks','reqn_requisition_remarks.rqrem_reqn_id = reqn_requisitions.rq_id','left');
$this->db->join('tukai_plants_4sale','tukai_plants_4sale.plsal_id = reqn_requisitions.rq_plant_4sale_code','left');
$this->db->join('tukai_pots','tukai_pots.pot_id = tukai_plants_4sale.plsal_pot_id','left');
$this->db->where('reqn_requisition_remarks.rqrem_remark_datetime IN(SELECT MAX(rqrem_remark_datetime) AS dt FROM reqn_requisition_remarks GROUP BY rqrem_reqn_id', NULL, FALSE);
$this->db->where('table_name.rq_challan_id', 0);
$this->db->order_by("table_name.rq_id","desc");
$query = $this->db->get();
return $query->result();
An alternative:
If your query (anyhow) cannot be written using CI's Active Record, you can always use a simple method:
$this->db->query('<your SQL query here>');
For example:
$query = $this->db->query('SELECT rq_id, rq_plant_4sale_code, rq_serial_number,rq_quantity_requested, rq_requester_farm_id,rq_fulfiller_farm_id, rqpri_description,rqrem_remark,rqrem_remark_datetime, rq_created_datetime,
plsal_name_botanical, plsal_name_english, pot_code, rqpri_description
FROM (reqn_requisitions)
LEFT JOIN reqn_requisition_priorities ON(rq_priority_rank=rqpri_rank)
LEFT JOIN reqn_requisition_remarks ON(rq_id=rqrem_reqn_id)
LEFT JOIN tukai_plants_4sale ON(rq_plant_4sale_code=plsal_id)
LEFT JOIN tukai_pots ON(plsal_pot_id=pot_id)
WHERE rqrem_remark_datetime IN(SELECT MAX(rqrem_remark_datetime) AS dt FROM reqn_requisition_remarks GROUP BY rqrem_reqn_id ) AND rq_challan_id=0');
return $query->result();

Related

Codeigniter INNER JOIN with multiple ON [duplicate]

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.

Magento 2 filterBuilder left join

I'm trying to filter product collection with multiple OR filter with this code :
$values = ['xxx','xxx'];
$filters = [];
$filters[] = $this->_filterBuilder
->setField('field_a')->setConditionType('in')
->setValue($values)
->create();
$filters[] = $this->_filterBuilder
->setField('field_b')
->setConditionType('in')
->setValue($values)
->create();
// two more filter like that
$filterGroup = $this->_filterGroupBuilder
->setFilters($filters)
->create();
$searchCriteria = $this->_searchCriteriaBuilder
->setFilterGroups([$filterGroup])
->create();
$products = $this->_productRepository->getList($searchCriteria)->getItems();
Problem is collection return 0 result instead of two. After analyze sql query generated by Magento eav table are joined with INNER JOIN like that :
INNER JOIN `catalog_product_entity_text` AS `at_field_b` ON (`at_field_b`.`row_id` = `e`.`row_id`) AND (`at_field_b`.`attribute_id` = '204') AND (`at_field_b`.`store_id` = 0)
If on raw sql query I execute it by replacing INNER JOIN by LEFT JOIN it works, i've got my results.
So my question is how can I "force" magento to left join instead of inner ? Or maybe it's a pure coincidence and real reason isn't the left/inner join
I didn't precise but field_a,field_b,etc... aren't not required so they could be empty for products

MySQL query getting a string value from query result

I have a query as follows:
SELECT *
FROM tb_circulares LEFT JOIN tb_colegios ON tb_circulares.colegio_circular = tb_colegios.id_colegio
LEFT JOIN tb_circulares_clase ON tb_circulares.codigo_circular = tb_circulares_clase.circular
LEFT JOIN tb_clases ON tb_circulares_clase.clase = tb_clases.id_clase
WHERE colegio_circular = 17
The query output shows three rows.
One of the row columns is the value for the field tb_circular_clase.nombre_clase
I would like to get a string containing the three resulting values for tb_circular_clase.nombre_clase.
For example:
row1-> nombre_clase = "1º primaria"
row2-> nombre_clase = "3ª secundaria"
row3-> nombre_clase = "4º primaria"
Is it possible to get a resulting query field with the final value?
`resultado = "1º primaria - 3ª secundaria - 4º primaria"
Thanks
Sounds like you're after group_concat(), which is an aggregation function concatenating all values of a group.
SELECT group_concat(nombre SEPARATOR ' - ') resultado
FROM tb_circulares
LEFT JOIN tb_colegios
ON tb_circulares.colegio_circular = tb_colegios.id_colegio
LEFT JOIN tb_circulares_clase
ON tb_circulares.codigo_circular = tb_circulares_clase.circular
LEFT JOIN tb_clases
ON tb_circulares_clase.clase = tb_clases.id_clase
WHERE colegio_circular = 17;

Left Join not returning Null or Non-matching values

I want to return all values from PF_OUTPUT where the token ID equals "AdmissionInfo" as well as the matching results from PF_RESULTS just for PAT_SEQ = 105566168.
I've looked at some other questions and I have included the null statement within the Left join where clause, however it still is just returning matching values.
SELECT CCDEV.PF_OUTPUT.TOKEN_NAME,
CCDEV.PF_OUTPUT.DISPLAY_SEQ,
CCDEV.PF_OUTPUT.RES_SEQ,
CCDEV.PF_OUTPUT.LABEL_SEQ,
CCDEV.PF_OUTPUT.DISPLAY_RESULT_NAME,
CCDEV.PF_OUTPUT.OUTPUT_RESULT_NAME,
CCDEV.PF_OUTPUT.OUTPUT_FIELD_NAME,
PF_RESULTS.PERFORM_DDT,
PF_RESULTS.CHART_DDT,
PF_RESULTS.STAFF_SEQ,
PF_RESULTS.RESULT_VALUE,
PF_RESULTS.STATUS,
PF_RESULTS.PF_RESULTS_SEQ,
PF_RESULTS.PAT_SEQ,
PF_RESULTS.PF_RESULT_SEQ,
PF_RESULTS.RECORD_VERSION,
PF_RESULTS.LABEL_SEQ AS LABEL_SEQ1
FROM CCDEV.PF_OUTPUT
LEFT JOIN PF_RESULTS
ON CCDEV.PF_OUTPUT.LABEL_SEQ = PF_RESULTS.LABEL_SEQ
AND CCDEV.PF_OUTPUT.RES_SEQ = PF_RESULTS.RES_SEQ
WHERE (CCDEV.PF_OUTPUT.TOKEN_NAME = 'AdmissionInfo'
AND PF_RESULTS.PAT_SEQ = 105566168)
OR (CCDEV.PF_OUTPUT.TOKEN_NAME = 'AdmissionInfo'
AND PF_RESULTS.PAT_SEQ IS NULL)
ORDER BY CCDEV.PF_OUTPUT.TOKEN_NAME,
CCDEV.PF_OUTPUT.DISPLAY_SEQ
Move PF_RESULTS.PAT_SEQ = 105566168 line from your where condition to your ON clause of the join.
SELECT CCDEV.PF_OUTPUT.TOKEN_NAME,
CCDEV.PF_OUTPUT.DISPLAY_SEQ,
CCDEV.PF_OUTPUT.RES_SEQ,
CCDEV.PF_OUTPUT.LABEL_SEQ,
CCDEV.PF_OUTPUT.DISPLAY_RESULT_NAME,
CCDEV.PF_OUTPUT.OUTPUT_RESULT_NAME,
CCDEV.PF_OUTPUT.OUTPUT_FIELD_NAME,
PF_RESULTS.PERFORM_DDT,
PF_RESULTS.CHART_DDT,
PF_RESULTS.STAFF_SEQ,
PF_RESULTS.RESULT_VALUE,
PF_RESULTS.STATUS,
PF_RESULTS.PF_RESULTS_SEQ,
PF_RESULTS.PAT_SEQ,
PF_RESULTS.PF_RESULT_SEQ,
PF_RESULTS.RECORD_VERSION,
PF_RESULTS.LABEL_SEQ AS LABEL_SEQ1
FROM CCDEV.PF_OUTPUT
LEFT JOIN PF_RESULTS
ON CCDEV.PF_OUTPUT.LABEL_SEQ = PF_RESULTS.LABEL_SEQ
AND CCDEV.PF_OUTPUT.RES_SEQ = PF_RESULTS.RES_SEQ
AND PF_RESULTS.PAT_SEQ = 105566168
WHERE (CCDEV.PF_OUTPUT.TOKEN_NAME = 'AdmissionInfo')
OR (CCDEV.PF_OUTPUT.TOKEN_NAME = 'AdmissionInfo'
AND PF_RESULTS.PAT_SEQ IS NULL)
ORDER BY CCDEV.PF_OUTPUT.TOKEN_NAME,
CCDEV.PF_OUTPUT.DISPLAY_SEQ
When you include a column from the RIGHT table of your LEFT join you essentially eliminate the LEFT join and make it an inner join. Unless you are saying where RIGHTTable.column IS NULL.
It looks like you're using the left-joined table in the where clause. This effectively makes it an inner join since any record that doesn't exist wil always yield false.
Unless of course the check in the where clause includes an 'is null' check.
You should move the PF_RESULTS.PAT_SEQ = 105566168 check to the on clause of the left join to fix this.

mysql select from a view with where condition gives different result than executing the view definition with where condition

I have a view with the following definition:
select
`cb_trans_detail`.`numero_partida` AS `numero_partida`,
`cb_trans_head`.`fecha_partida` AS `fecha_partida`,
`cb_trans_detail`.`concepto_partida` AS `concepto_partida`,
`cb_cuenta`.`nombre_cuenta` AS `nombre_cuenta`,
`cb_cuenta`.`codigo_mayor` AS `codigo_mayor`,
`cb_mayor`.`nombre_mayor` AS `nombre_mayor`,
`cb_mayor`.`categoria` AS `categoria`,
`cb_categoria`.`nombre` AS `nombre`,
`cb_categoria`.`presentacion` AS `presentacion`,
`cb_trans_detail`.`codigo_cuenta` AS `codigo_cuenta`,
sum(`cb_trans_detail`.`debito_partida`) AS `Debitos`,
sum(`cb_trans_detail`.`credito_partida`) AS `Creditos`,
`cb_cuenta`.`saldo_inicial` AS `saldo_inicial`,
((`cb_cuenta`.`saldo_inicial` +
sum(`cb_trans_detail`.`debito_partida`)) -
sum(`cb_trans_detail`.`credito_partida`)) AS `Saldo`,
concat(`cb_mayor`.`categoria`,`cb_cuenta`.`codigo_mayor`,`cb_trans_detail`.`codigo_cuenta`)
AS `Codigo`
from
((((`cb_trans_detail` join `cb_cuenta`
on(((`cb_trans_detail`.`codigo_cuenta` = `cb_cuenta`.`codigo_cuenta`)
and (`cb_trans_detail`.`categoria` = `cb_cuenta`.`categoria`)
and (`cb_trans_detail`.`codigo_mayor` = `cb_cuenta`.`codigo_mayor`))))
join `cb_mayor` on(((`cb_cuenta`.`codigo_mayor` = `cb_mayor`.`codigo_mayor`)
and (`cb_cuenta`.`categoria` = `cb_mayor`.`categoria`))))
join `cb_categoria` on(((`cb_mayor`.`categoria` = `cb_categoria`.`categoria`)
and (`cb_trans_detail`.`categoria` = `cb_categoria`.`categoria`))))
left join `cb_trans_head` on((`cb_trans_detail`.`numero_partida` =
`cb_trans_head`.`numero_partida`)))
where
(`cb_categoria`.`presentacion` = '1')
group by concat(`cb_mayor`.`categoria`,`cb_cuenta`.`codigo_mayor`,
`cb_trans_detail`.`codigo_cuenta`)
If I select from this view as follows:
SELECT
`balance_general_view`.`numero_partida`,
`balance_general_view`.`fecha_partida`,
`balance_general_view`.`concepto_partida`,
`balance_general_view`.`nombre_cuenta`,
`balance_general_view`.`codigo_mayor`,
`balance_general_view`.`nombre_mayor`,
`balance_general_view`.`categoria`,
`balance_general_view`.`nombre`,
`balance_general_view`.`presentacion`,
`balance_general_view`.`codigo_cuenta`,
`balance_general_view`.`Debitos`,
`balance_general_view`.`Creditos`,
`balance_general_view`.`saldo_inicial`,
`balance_general_view`.`Saldo`,
`balance_general_view`.`Codigo`
FROM
`balance_general_view`
WHERE
`balance_general_view`.`fecha_partida` BETWEEN '2014-01-01' AND '2014-01-31'
this yields a different result than if I execute the query as follows:
select
`cb_trans_detail`.`numero_partida` AS `numero_partida`,
`cb_trans_head`.`fecha_partida` AS `fecha_partida`,
`cb_trans_detail`.`concepto_partida` AS `concepto_partida`,
`cb_cuenta`.`nombre_cuenta` AS `nombre_cuenta`,
`cb_cuenta`.`codigo_mayor` AS `codigo_mayor`,
`cb_mayor`.`nombre_mayor` AS `nombre_mayor`,
`cb_mayor`.`categoria` AS `categoria`,
`cb_categoria`.`nombre` AS `nombre`,
`cb_categoria`.`presentacion` AS `presentacion`,
`cb_trans_detail`.`codigo_cuenta` AS `codigo_cuenta`,
sum(`cb_trans_detail`.`debito_partida`) AS `Debitos`,
sum(`cb_trans_detail`.`credito_partida`) AS `Creditos`,
`cb_cuenta`.`saldo_inicial` AS `saldo_inicial`,
((`cb_cuenta`.`saldo_inicial` + sum(`cb_trans_detail`.`debito_partida`)) - sum(`cb_trans_detail`.`credito_partida`)) AS `Saldo`,
concat(`cb_mayor`.`categoria`,`cb_cuenta`.`codigo_mayor`,`cb_trans_detail`.`codigo_cuenta`) AS `Codigo`
from
((((`cb_trans_detail` join `cb_cuenta` on(((`cb_trans_detail`.`codigo_cuenta` = `cb_cuenta`.`codigo_cuenta`) and (`cb_trans_detail`.`categoria` = `cb_cuenta`.`categoria`) and (`cb_trans_detail`.`codigo_mayor` = `cb_cuenta`.`codigo_mayor`)))) join `cb_mayor` on(((`cb_cuenta`.`codigo_mayor` = `cb_mayor`.`codigo_mayor`) and (`cb_cuenta`.`categoria` = `cb_mayor`.`categoria`)))) join `cb_categoria` on(((`cb_mayor`.`categoria` = `cb_categoria`.`categoria`) and (`cb_trans_detail`.`categoria` = `cb_categoria`.`categoria`)))) left join `cb_trans_head` on((`cb_trans_detail`.`numero_partida` = `cb_trans_head`.`numero_partida`)))
where
(`cb_categoria`.`presentacion` = '1') and `cb_trans_head`.`fecha_partida` BETWEEN '2014-01-01' and '2014-01-31'
group by
concat(`cb_mayor`.`categoria`,`cb_cuenta`.`codigo_mayor`,`cb_trans_detail`.`codigo_cuenta`)
My question is: How to get the result I need using the view and filtering programatically instead of hard-coding the where condition? Thank you. If you need the individual table definitions let me know. Much appreciated.
If you use a left join to a table X and a condition in the WHERE-clause to this table X, you change your left join to an inner one. If you want to restrict the results by the values of this left joined table, you must use this condition in the ON clause of the left join instead:
...
LEFT JOIN
cb_trans_head
ON
cb_trans_detail.numero_partida = cb_trans_head.numero_partida
AND
cb_trans_head.fecha_partida BETWEEN '2014-01-01' and '2014-01-31'
...
If there's another one that I overlook, tread it the same way.