Cannot use alias from SELECT clause in the WHERE clause - mysql

USE stormtrooper_java;
SELECT imperial_battlegroup.BGID, imperial_battlegroup.Designation, imperial_battlegroup.HQ_LocationX, imperial_battlegroup.HQ_LocationY,
stormtrooper_unit.STUID, stormtrooper_unit.UnitCmd, stormtrooper_unit.UnitType, stormtrooper_unit.Location_X, stormtrooper_unit.Location_Y,
ABS(stormtrooper_unit.Location_X - stormtrooper_unit.Location_Y) AS XYRange
from imperial_battlegroup inner join
stormtrooper_unit
on imperial_battlegroup.BGID = stormtrooper_unit.UnitCmd
WHERE Designation = 'Battle Group I' and UnitType = 'Aslt Infantry' AND
XYRange > 100;
When I execute the file without XYRange > 100 it works very well, but I do need that filtering logic in the query.
How can I adjust my query to filter the results by this calculated condition?

SQL does not allow you to use column aliases in WHERE clauses. It does extend the HAVING, so one solution is:
SELECT bg.BGID, bg.Designation, imperial_battlegroup.HQ_LocationX, bg.HQ_LocationY,
u.STUID, u.UnitCmd, u.UnitType, u.Location_X, u.Location_Y,
ABS(stormtrooper_unit.Location_X - stormtrooper_unit.Location_Y) AS XYRange
from imperial_battlegroup bg inner join
stormtrooper_unit
on bg.BGID = u.UnitCmd
WHERE Designation = 'Battle Group I' and UnitType = 'Aslt Infantry'
HAVING XYRange > 100;
Another option is to repeat the expression in the WHERE.

Try this:
SELECT imperial_battlegroup.BGID, imperial_battlegroup.Designation,
imperial_battlegroup.HQ_LocationX, imperial_battlegroup.HQ_LocationY,
stormtrooper_unit.STUID, stormtrooper_unit.UnitCmd,
stormtrooper_unit.UnitType, stormtrooper_unit.Location_X,
stormtrooper_unit.Location_Y,
ABS(stormtrooper_unit.Location_X - stormtrooper_unit.Location_Y) AS XYRange
from imperial_battlegroup inner join
stormtrooper_unit
on imperial_battlegroup.BGID = stormtrooper_unit.UnitCmd
WHERE Designation = 'Battle Group I' and UnitType = 'Aslt Infantry' AND
ABS(stormtrooper_unit.Location_X - stormtrooper_unit.Location_Y) > 100;
Just updated the last line, rest everything is same.

Its forbidden to use alias in where clause. So use the function itself
where ABS(stormtrooper_unit.Location_X - stormtrooper_unit.Location_Y)> 100

Related

SqlAlchemy puts SELECT Subquery in FROM clause instead of SELECT

My target SQL is the following, which is valid,
SELECT a.agreement_group_id,
(select id from agreement_t where agreement_group_id = a.agreement_group_id and
active = 'Y'),
...
FROM ets.agreement_t a
WHERE requester_uniqueidentifier = '0010079170'
GROUP BY a.agreement_group_id
ORDER BY a.agreement_group_id
But SqlAlchemy is producing the following -- and complaining that I don't have anon_1 in GROUP BY due to its placement of the sub-select in FROM,
SELECT agreement_t_1.agreement_group_id AS agreement_t_1_agreement_group_id,
anon_1.id AS anon_1_id,
...
FROM ets.agreement_t AS agreement_t_1,
(SELECT ets.agreement_t.id AS id
FROM ets.agreement_t, ets.agreement_t AS agreement_t_1
WHERE ets.agreement_t.agreement_group_id = agreement_t_1.agreement_group_id AND
ets.agreement_t.active = 'Y') AS anon_1
WHERE agreement_t_1.requester_uniqueidentifier = '0010079170'
GROUP BY agreement_t_1.agreement_group_id, anon_1.id
ORDER BY agreement_t_1.agreement_group_id
Python SqlAlchemy code:
agreement = aliased(AgreementT)
subqueryActive = db_session.query(AgreementT.id).filter(
(AgreementT.agreement_group_id == agreement.agreement_group_id),
(AgreementT.active == 'Y')
).subquery()
result = (db_session.query(
agreement.agreement_group_id,
subqueryActive,
...
.filter(*filters)
.group_by(agreement.agreement_group_id)
.order_by(agreement.agreement_group_id)
.all())
I don't need any other Joins. As you can see, the subquery subqueryActive already references the alias agreement which is used in the main query. So why is the Sub-Select not placed properly in the SELECT, but rather in the FROM, with the following error?
psycopg2.errors.GroupingError: column "anon_1.id" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: ...ent_group_id AS agreement_t_1_agreement_group_id, anon_1.id ...
^
If the sub-Select should be part of the SELECT, we can't use .subquery(), we need to use .label() instead.
Example here: https://stackoverflow.com/a/43655840/1005607
Thanks for the tip #Ilja Everilä

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.

How to use "MAX" in codeigniter where?

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

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.

remove zero in mysql field using join

code = 00000000005555
2nd option code = 00000000000555
hi i am try to find out same function like ltrim() of php
SELECT * FROM db1.stock JOIN db2.prodinfo ON replace(db2.prodinfo.code,0000000000,'') = replace(db1.stock.code,0000000000,'') WHERE db1.stock.InvNo ='12' and db2.prodinfo.Cat = 'super'
i rum this temporary. becuse zero might be increase and decrease i
example above. i am just want to remove zero in this query
thanks
try by casting it into numeric,
SELECT *
FROM db1.stock JOIN db2.prodinfo ON
CAST(db2.prodinfo.code AS SIGNED) = CAST(db1.stock.code AS SIGNED)
WHERE db1.stock.InvNo ='12' and db2.prodinfo.Cat = 'super'
or
SELECT *
FROM db1.stock JOIN db2.prodinfo ON
CAST(db2.prodinfo.code AS DECIMAL(15,0)) = CAST(db1.stock.code AS AS DECIMAL(15,0))
WHERE db1.stock.InvNo ='12' and db2.prodinfo.Cat = 'super'