Sql Not unique table/alias - mysql

I have sql query:
SELECT leads.lead_id,
attributes.code AS attributeCode,
leads_notes.content AS noteContent,
leads_notes.task_type_id,
task_types.type_name
FROM leads,
leads_notes
INNER JOIN task_types
ON task_types.task_type_id = leads_notes.task_type_id
INNER JOIN leads_attributes
ON leads_attributes.lead_id = leads.lead_id
INNER JOIN attributes
ON attributes.attribute_id = leads_attributes.attribute_id
INNER JOIN leads_notes
ON leads_notes.lead_id = leads.lead_id
WHERE ( leads.ambassador = 1
OR leads.rents_bike = 1 )
AND ( leads.city <> '' )
AND ( leads.address <> ''
OR leads.address2 <> '' )
AND ( leads.country_id <> '' )
AND ( leads_attributes.attribute_id IN ( $attributes_id ) )
AND ( leads.lead_id = $lead_id )
But I get error:
Syntax error or access violation: 1066 Not unique table/alias:
'leads_notes''
How can I solve it? Thanks.

Never use commas in the FROM clause. Always use proper, explicit JOIN syntax.
In your case you also had lead_notes twice in the FROM clause. It is easier to write and read the query if you use table aliases:
SELECT l.lead_id, a.code as attributeCode, ln.content as noteContent, ln.task_type_id, tt.type_name
FROM leads l JOIN
leads_notes ln
ON ln.lead_id = l.lead_id JOIN
task_types tt
ON tt.task_type_id = ln.task_type_id JOIN
leads_attributes la
ON la.lead_id = l.lead_id JOIN
attributes a
ON a.attribute_id = la.attribute_id
WHERE (l.ambassador=1 OR l.rents_bike=1) AND
(l.city <> '') AND
(l.address <>'' OR l.address2 <>'') AND
(l.country_id <> '') AND
(la.attribute_id IN ($attributes_id)) AND
(l.lead_id = $lead_id);

You have add leads_notes table double: one in after leads table and another in inner join, so remove one solve your problem like following
SELECT leads.lead_id,
attributes.code AS attributeCode,
leads_notes.content AS noteContent,
leads_notes.task_type_id,
task_types.type_name
FROM leads
INNER JOIN task_types
ON task_types.task_type_id = leads_notes.task_type_id
INNER JOIN leads_attributes
ON leads_attributes.lead_id = leads.lead_id
INNER JOIN attributes
ON attributes.attribute_id = leads_attributes.attribute_id
INNER JOIN leads_notes
ON leads_notes.lead_id = leads.lead_id
WHERE ( leads.ambassador = 1
OR leads.rents_bike = 1 )
AND ( leads.city <> '' )
AND ( leads.address <> ''
OR leads.address2 <> '' )
AND ( leads.country_id <> '' )
AND ( leads_attributes.attribute_id IN ( $attributes_id ) )
AND ( leads.lead_id = $lead_id )

Related

Update sentence with subquery on MySQL

I have the following sentence, that returns the error
Unknown column targets.ID_TARGET in where clause
and I can't find any solution. Could you guys help?
The proposal is update 'sw_automatic' for each row with the value that th subquery provides (0 or 1)
update bt_pry_targets targets
set targets.sw_automatic = (
(
SELECT (CASE WHEN Task.ID_TP_TASKS_GROUPS = 694 THEN '0' ELSE '1' END) AS TYPE_TASK,
Task.ID_TASK FROM bt_tasks AS Task
INNER JOIN bt_pry_cmp_workflows AS BtCmpWorkflows ON (Task.ID_PRY_CMP_WORKFLOW = BtCmpWorkflows.ID_PRY_CMP_WORKFLOW)
INNER JOIN bt_pry_components AS PryComponent ON (PryComponent.ID_PRY_COMPONENT = BtCmpWorkflows.ID_PRY_COMPONENT )
INNER JOIN bt_components AS Component ON (PryComponent.ID_COMPONENT = Component.ID_COMPONENT)
INNER JOIN bt_pry_targets AS PryTarget ON (PryComponent.ID_TARGET = PryTarget.ID_TARGET)
INNER JOIN bt_flows AS Flows ON (Flows.ID_FLOW = Task.ID_FLOW)
WHERE Flows.SW_END_DEPENDENCE = 1
AND PryTarget.ID_TARGET = targets.ID_TARGET
GROUP BY Task.ID_TASK) )
where targets.sw_automatic is null;
In you subquery the column targets.ID_TARGET in not visible
so you could try using you subquery as a join table for updated
update bt_pry_targets targets
inner join (
SELECT (CASE WHEN Task.ID_TP_TASKS_GROUPS = 694 THEN '0' ELSE '1' END) AS TYPE_TASK,
Task.ID_TASK FROM bt_tasks AS Task
INNER JOIN bt_pry_cmp_workflows AS BtCmpWorkflows ON (Task.ID_PRY_CMP_WORKFLOW = BtCmpWorkflows.ID_PRY_CMP_WORKFLOW)
INNER JOIN bt_pry_components AS PryComponent ON (PryComponent.ID_PRY_COMPONENT = BtCmpWorkflows.ID_PRY_COMPONENT )
INNER JOIN bt_components AS Component ON (PryComponent.ID_COMPONENT = Component.ID_COMPONENT)
INNER JOIN bt_pry_targets AS PryTarget ON (PryComponent.ID_TARGET = PryTarget.ID_TARGET)
INNER JOIN bt_flows AS Flows ON (Flows.ID_FLOW = Task.ID_FLOW)
WHERE Flows.SW_END_DEPENDENCE = 1
AND PryTarget.ID_TARGET = targets.ID_TARGET
GROUP BY Task.ID_TASK
) t on t.PryTarget = targets.ID_TARGET
AND targets.sw_automatic is null
set targets.sw_automatic = t.TYPE_TASK

Parentheses in mysql query giving different results

I have a query that is giving me different results when i enclosed it in Parentheses, however when I run it without Parentheses its giving me different results. I want to apply Union in between so I have to use Parentheses as without union doesn't work.
The query is as follows:
SELECT Distinct
recurring_billing.id,
recurring_billing.kid_id,
recurring_billing.class_id,
recurring_billing.app_id,
recurring_billing.Region_ID,
CC.month_name,
CC.billing_year,
CASE
WHEN
CC.month_name = recurring_billing.billing_month
AND CC.billing_year = recurring_billing.billing_year
THEN
recurring_billing.billing_status
ELSE
'Pending'
END
AS billing_status, tblkids.kid_name, tblkids.kid_Lastname, tblkids.kid_EMail, tbl_app.app_CCExp AS cc_exp, tbl_app.app_CCName AS cc_name, tbl_app.app_CCNumber AS cc_number, tbl_app.app_CCType AS cc_type, tblclasses.cla_EndDate, tblclassdays.classday_day, CC.remainingclasses, tbl_app.cost_per_class, CC.remainingclasses * tbl_app.cost_per_class AS cost_amount,
CASE
WHEN
OP.override_amt IS NOT NULL
THEN
OP.override_amt
ELSE
CC.remainingclasses * tbl_app.cost_per_class
END
AS pmt_amount,
CASE
WHEN
OP.process_payment = False
THEN
OP.process_payment
ELSE
True
END
AS process_payment
FROM
recurring_billing
LEFT JOIN
tblkidsxclass
ON recurring_billing.kid_id = tblkidsxclass.kxc_kidid
AND recurring_billing.app_id = tblkidsxclass.kxc_appid
LEFT JOIN
tbl_app
ON recurring_billing.app_ID = tbl_app.app_ID
LEFT JOIN
tblkids
ON recurring_billing.kid_id = tblkids.kid_ID
LEFT JOIN
tblclasses
ON recurring_billing.class_id = tblclasses.cla_ID
LEFT JOIN
tblclassdays
ON tblclasses.cla_ID = tblclassdays.classday_classID
INNER JOIN
(
SELECT
MONTHNAME(classday_day) AS month_name,
YEAR(classday_day) AS billing_year,
cla_ID,
COUNT(classday_classid) AS remainingclasses,
c.cost_per_class AS cost_per_class,
COUNT(classday_classid) * cost_per_class AS TotalClassCost
FROM
tblclassdays
JOIN
(
SELECT
tblclasses.cla_ID,
tblclasses.cost_per_class,
tblclasses.cla_nextclass AS next1,
tblclasses_1.cla_nextclass AS next2
FROM
tblclasses
LEFT JOIN
tblclasses AS tblclasses_1
ON tblclasses.cla_nextclass = tblclasses_1.cla_ID
WHERE
tblclasses.cla_ID IN
(
SELECT DISTINCT
recurring_billing.class_id
FROM
recurring_billing
LEFT JOIN
tblkidsxclass
ON recurring_billing.kid_id = tblkidsxclass.kxc_kidid
AND recurring_billing.app_id = tblkidsxclass.kxc_appid -- LEFT JOIN tblkids ON recurring_billing.kid_id = tblkids.kid_ID
LEFT JOIN
tblclasses
ON recurring_billing.class_id = tblclasses.cla_ID -- LEFT JOIN tblclassdays ON tblclasses.cla_ID = tblclassdays.classday_classID
WHERE
ISNULL(tblkidsxclass.kxc_dropoutdate)
AND tblkidsxclass.pmt_option = 'Recurring'
AND tblclasses.cla_active = TRUE -- AND tblclasses.cla_EndDate >= NOW()
GROUP BY
recurring_billing.id
)
)
c
ON tblclassdays.classday_classid IN
(
c.cla_ID,
c.next1,
c.next2
)
WHERE
tblclassdays.classday_noclass = FALSE
AND MONTH(classday_day) = 11
AND YEAR(classday_day) = 2020
AND
(
CONCAT(CAST(classday_day AS DATE), ' ', CAST(classday_endtime AS TIME)) > CAST(CURDATE() AS DATETIME)
)
GROUP BY
cla_ID
)
CC
ON CC.cla_ID = tblclassdays.classday_classID
LEFT JOIN
override_payments OP
ON recurring_billing.app_id = OP.app_id
AND recurring_billing.kid_id = OP.kid_id
AND CC.month_name = OP.billing_month
AND CC.billing_year = OP.billing_year
WHERE
ISNULL(tblkidsxclass.kxc_dropoutdate)
AND tblkidsxclass.pmt_option = 'Recurring'
AND tblclasses.cla_active = TRUE
AND recurring_billing.kid_id NOT IN
(
SELECT
kid_id
from
recurring_billing
where
billing_month = 'November'
and billing_year = '2020'
)
-- AND tblclasses.cla_EndDate >= NOW()
GROUP BY
recurring_billing.id
ORDER BY
recurring_billing.id ASC
Same query if enclosed in Parentheses will give me different results.
Parentheses are not required for a UNION statement. The following 2 union statements both work and yield the same results.
SELECT 1 UNION SELECT 2;
(SELECT 1) UNION (SELECT 2);

UPDATE - SELECT - MYSQL #1093 - You can't specify target table 'temp1' for update in FROM clause

I can't find solution to correct this big query, I always receive an error from database.
I have tre tables and I need to make changes on some attribute on some condition:
UPDATE o36t_orders as temp1,
mytable as temp2
SET
temp1.bonifico = 1,
temp2.ultimo = 1
WHERE
temp1.id_order IN (
SELECT
id_order
FROM o36t_orders
LEFT JOIN o36t_address ON (o36t_address.id_address = o36t_orders.id_address_delivery)
LEFT JOIN mytable ON (
mytable.Causale = CONCAT(
o36t_address.lastname,
' ',
o36t_address.firstname
)
)
WHERE
o36t_orders.bonifico <> 1
)
AND temp2.id IN (
SELECT
id
FROM o36t_orders
LEFT JOIN o36t_address ON (o36t_address.id_address = o36t_orders.id_address_delivery)
LEFT JOIN mytable ON (
mytable.Causale = CONCAT(
o36t_address.lastname,
' ',
o36t_address.firstname
)
)
WHERE
o36t_orders.bonifico <> 1
)
Since the subqueries of the 2 IN clauses are identical (except the retuned column), I think that you can do what you want by a straight inner join of the 2 tables and that subquery (returning both columns):
UPDATE o36t_orders temp1
INNER JOIN (
SELECT
id, id_order
FROM o36t_orders
LEFT JOIN o36t_address ON (o36t_address.id_address = o36t_orders.id_address_delivery)
LEFT JOIN mytable ON (
mytable.Causale = CONCAT(
o36t_address.lastname,
' ',
o36t_address.firstname
)
)
WHERE
o36t_orders.bonifico <> 1
) t ON t.id_order = temp1.id_order
INNER JOIN mytable temp2 ON temp2.id = t.id
SET
temp1.bonifico = 1,
temp2.ultimo = 1

Unknown column in 'IN/ALL/ANY subquery'

Why am I getting this error? Error is showing up in the OR clause, but I'm selecting gl_ID inside the SELECT statement.
; DECLARE v_firstDate DATETIME
SET #p_ID = 368
SELECT SUBDATE(NOW(), 1) INTO v_firstDate;
SELECT t_ID, t_firstName, t_lastName
FROM t_table
WHERE
((#p_ID IN (
SELECT tt_ID
FROM tt_tableTwo
INNER JOIN st_stats ON (st_ID = tt_ID)
INNER JOIN da_data ON (da_ID = st_ID AND da_name IN ("allCompanies", "allglobals"))
)
))
OR
(
(gl_ID IN ( //problem is here
SELECT gl_ID
FROM gl_globals
INNER JOIN tr_transport ON (tr_id = gl_caseID AND tr_idOther = #p_ID)
INNER JOIN co_countries ON (co_ID = gl_ID AND co_ID = #p_ID)
)
)
)
Error message:
Unknown column 'gl_ID' in 'IN/ALL/ANY subquery'
Should I be using an AS or a HAVING?
gl_ID is not accessible in the OR clause because it doesn't exist in t_table. An inner join under the first FROM clause solves the problem.
; DECLARE v_firstDate DATETIME
SET #p_ID = 368
SELECT SUBDATE(NOW(), 1) INTO v_firstDate;
SELECT t_ID, t_firstName, t_lastName
FROM t_table
INNER JOIN gl_globals ON (t_ID = gl_ID) // fix
WHERE
((#p_ID IN (
SELECT tt_ID
FROM tt_tableTwo
INNER JOIN st_stats ON (st_ID = tt_ID)
INNER JOIN da_data ON (da_ID = st_ID AND da_name IN ("allCompanies", "allglobals"))
)
))
OR
(
(gl_ID IN (
SELECT gl_ID
FROM gl_globals
INNER JOIN tr_transport ON (tr_id = gl_caseID AND tr_idOther = #p_ID)
INNER JOIN co_countries ON (co_ID = gl_ID AND co_ID = #p_ID)
)
)
)

MySQL group by kills the query performance

I have MySQL query currently selecting and joining 13 tables and finally grouping ~60k rows. The query without grouping takes ~0ms but with grouping the query time increases to ~1.7sec. The field, which is used for grouping is primary field and is indexed. Where could be the issue?
I know group by without aggregate is considered invalid query and bad practise but I need distinct base table rows and can not use DISTINCT syntax.
The query itself looks like this:
SELECT `table_a`.*
FROM `table_a`
LEFT JOIN `table_b`
ON `table_b`.`invoice` = `table_a`.`id`
LEFT JOIN `table_c` AS `r1`
ON `r1`.`invoice_1` = `table_a`.`id`
LEFT JOIN `table_c` AS `r2`
ON `r2`.`invoice_2` = `table_a`.`id`
LEFT JOIN `table_a` AS `i1`
ON `i1`.`id` = `r1`.`invoice_2`
LEFT JOIN `table_a` AS `i2`
ON `i2`.`id` = `r2`.`invoice_1`
JOIN `table_d` AS `_u0`
ON `_u0`.`id` = 1
LEFT JOIN `table_e` AS `_ug0`
ON `_ug0`.`user` = `_u0`.`id`
JOIN `table_f` AS `_p0`
ON ( `_p0`.`enabled` = 1
AND ( ( `_p0`.`role` < 2
AND `_p0`.`who` IS NULL )
OR ( `_p0`.`role` = 2
AND ( `_p0`.`who` = '0'
OR `_p0`.`who` = `_u0`.`id` ) )
OR ( `_p0`.`role` = 3
AND ( `_p0`.`who` = '0'
OR `_p0`.`who` = `_ug0`.`group` ) ) ) )
AND ( `_p0`.`action` = '*'
OR `_p0`.`action` = 'read' )
AND ( `_p0`.`related_table` = '*'
OR `_p0`.`related_table` = 'table_name' )
JOIN `table_a` AS `_e0`
ON ( ( `_p0`.`related_id` = 0
OR `_p0`.`related_id` = `_e0`.`id`
OR `_p0`.`related_user` = `_e0`.`user`
OR `_p0`.`related_group` = `_e0`.`group` )
OR ( `_p0`.`role` = 0
AND `_e0`.`user` = `_u0`.`id` )
OR ( `_p0`.`role` = 1
AND `_e0`.`group` = `_ug0`.`group` ) )
AND `_e0`.`id` = `table_a`.`id`
JOIN `table_d` AS `_u1`
ON `_u1`.`id` = 1
LEFT JOIN `table_e` AS `_ug1`
ON `_ug1`.`user` = `_u1`.`id`
JOIN `table_f` AS `_p1`
ON ( `_p1`.`enabled` = 1
AND ( ( `_p1`.`role` < 2
AND `_p1`.`who` IS NULL )
OR ( `_p1`.`role` = 2
AND ( `_p1`.`who` = '0'
OR `_p1`.`who` = `_u1`.`id` ) )
OR ( `_p1`.`role` = 3
AND ( `_p1`.`who` = '0'
OR `_p1`.`who` = `_ug1`.`group` ) ) ) )
AND ( `_p1`.`action` = '*'
OR `_p1`.`action` = 'read' )
AND ( `_p1`.`related_table` = '*'
OR `_p1`.`related_table` = 'table_name' )
JOIN `table_g` AS `_e1`
ON ( ( `_p1`.`related_id` = 0
OR `_p1`.`related_id` = `_e1`.`id`
OR `_p1`.`related_user` = `_e1`.`user`
OR `_p1`.`related_group` = `_e1`.`group` )
OR ( `_p1`.`role` = 0
AND `_e1`.`user` = `_u1`.`id` )
OR ( `_p1`.`role` = 1
AND `_e1`.`group` = `_ug1`.`group` ) )
AND `_e1`.`id` = `table_a`.`company`
WHERE `table_a`.`date_deleted` IS NULL
AND `table_a`.`company` = 4
AND `table_a`.`type` = 1
AND `table_a`.`date_composed` >= '2016-05-04 14:43:55'
GROUP BY `table_a`.`id`
The ORs kill performance.
This composite index may help: INDEX(company, type, date_deleted, date_composed).
LEFT JOIN table_b ON table_b.invoice = table_a.id seems to do absolutely nothing other than slow down the processing. No fields of table_b are used or SELECTed. Since it is a LEFT join, it does not limit the output. Etc. Get rid if it, or justify it.
Ditto for other joins.
What happens with JOIN and GROUP BY: First, all the joins are performed; this explodes the number of rows in the intermediate 'table'. Then the GROUP BY implodes the set of rows.
One technique for avoiding this explode-implode sluggishness is to do
SELECT ...,
( SELECT ... ) AS ...,
...
instead of a JOIN or LEFT JOIN. However, that works only if there is zero or one row in the subquery. Usually this is beneficial when an aggregate (such as SUM) can be moved into the subquery.
For further discussion, please include SHOW CREATE TABLE.