Cant update and select in single query in mysql - mysql

UPDATE sub_categories
set creatives_count =
( SELECT COUNT(services.sub_category_id)
from sub_categories
left
join services
on (sub_categories.id = services.sub_category_id)
GROUP
BY sub_categories.id);
BlockquoteError: Table 'sub_categories' is specified twice, both as a target for 'UPDATE' and as a separate source for data.
How can I update my column with the result I obtained in subquery.

You can try below -
UPDATE sub_categories s
join
(
SELECT COUNT(services.sub_category_id) as cnt from sub_categories
left join services on sub_categories.id = services.sub_category_id
GROUP BY sub_categories.id
)A on s.id=A.id
set creatives_count = a.cnt

You could use inner join on the subquery
UPDATE sub_categories
INNER JOIN (
SELECT sub_categories.id my_id, COUNT(services.sub_category_id) my_count
FROM sub_categories
LEFT JOIN services ON sub_categories.id = services.sub_category_id
GROUP BY sub_categories.id) t ON t.my_id = sub_categories.id
SET creatives_count = t.my_count

Related

combine multiple select statement in SQL

I've just started learning SQL. Here is part of my Database:
I want to get the project name from the Project table with condition:
name = 'turbine' and value = '03' in Parameter table.
I have wrote the following query and it seems to work!
But I was wondering if any smarter query can do the job for me :
SELECT name
FROM Project
WHERE id IN (
SELECT projectId
FROM Cases
WHERE id IN (
SELECT caseId
FROM ParamValue
WHERE parameterId IN (SELECT id FROM Parameter WHERE name = 'turbine')
AND value = '03')
)
;
Instead of several nested IN clause with subquery seems more easy to read a proper set of inner join
select distinct Project.name
from Project
INNER JOIN Cases ON Cases.projectId = Project.id
INNER JOIN ParamValue ON ParamValue.caseId = Cases.id
AND ParamValue.value ='03'
INNER JOIN Parameter ON ParamValue.parameterId = Parameter.id
AND Parameter.name = 'turbine'
Sure here you go without subqueries:
SELECT pj.Name
FROM Parameter p
INNER JOIN ParamValue pv ON pv.Value = '03' AND p.Id = pv.parameterId
INNER JOIN Cases c ON pv.caseId = c.Id
INNER JOIN Project pj ON c.projectId = pj.Id
WHERE p.name = 'turbine'
;
select pr.name from Project pr
left join Cases c on pr.name = c.id
left join ParamValue pv on c.id = pv.parameterId
left join Parameter p on p.id = pv.parameterId
where p.name = 'turbine' and pv.value = '03';

Select the first record of another table inside a select - MYSQL

I´m trying to make a query listing all clients, and also get the last comment and
the date of that comment inside the table of history_client inside a single query for it to be listed.
select a.id_client,a.name,a.lastname,(select b.date_created,b.comentary
from history_of_client b where a.id_client = b.id_client_asociate) from clients_main_table
You could use an inner join on max(date_created) for id_client on history table and join
SELECT a.id_client,a.name,a.lastname, h.commentary
FROM clients_main_table a
INNER join (
select b.id_client_asociate, max(b.date_created) max_date
from history_of_client
group by b.id_client_asociate ) t on t.id_client_asociate = a.id_client
INNER JOIN history_of_client h on h.id_client_asociate = t.id_client_asociate
and h.date_created = t.max_date
Use the LEFT JOIN and INNER join to get your desired result set.
select a.id_client,
a.name,
a.lastname,
hc.date_created,
hc.comentary
from clients_main_table c
left join (select id_client_asociate,max(date_created) dt from history_of_client group by id_client_asociate) h
on (c.id_client = b.id_client_asociate)
inner join history_of_client hc
on (hc.id_client_asociate = b.id_client_asociate and hc.date_created = h.date_created)

Using SUM function in an update query with inner joins

Getting an error when running this
UPDATE FlightBooking
INNER JOIN Passenger ON Passenger.FlightBookingId=FlightBooking.FlightBookingId
INNER JOIN AirplaneSeat ON AirplaneSeat.AirplaneSeatId = Passenger.SeatId
INNER JOIN Section ON AirplaneSeat.SectionId = Section.SectionId
INNER JOIN ExtraCost ON ExtraCost.FlightBookingId=FlightBooking.FlightBookingId
INNER JOIN Luggage ON Luggage.LuggageId = ExtraCost.LuggageId
INNER JOIN SportsEquipment ON ExtraCost.SportsEquipmentId=SportsEquipment.SportsEquipmentId
INNER JOIN Insurance ON ExtraCost.InsuranceId = Insurance.InsuranceId
INNER JOIN CarHirePrice ON CarHirePrice.CarHirePriceId= ExtraCost.CarHirePriceId
INNER JOIN Route ON FlightBooking.RouteId = Route.RouteId
SET FlightBooking.TotalCost = (SUM(Section.PriceInflux+Route.RoutePrice+Luggage.Price+SportsEquipment.SportsEquipmentPrice+Insurance.Price+CarHirePrice.TotalPrice))
WHERE FlightBooking.FlightBookingId=1;
When I have it formed as a Select query it returns the correct value so all the tables are fine. I'm assuming my syntax is wrong.
Any help would be appreciated.
You should use the following syntax when using an aggregate in an update statement.
UPDATE t1
SET t1.field = t2.field2Sum
FROM table1 t1
INNER JOIN (select field3, sum(field2) as field2Sum
from table2
group by field3) as t2
on t2.field3 = t1.field3
See Below, I only scripted a few tables but you can see how to do the rest.
UPDATE FlightBooking set TotalCost = (ExtraCost.SumExtra + SumLuggage) From FlightBooking
INNER JOIN Passenger ON Passenger.FlightBookingId=FlightBooking.FlightBookingId
INNER JOIN AirplaneSeat ON AirplaneSeat.AirplaneSeatId = Passenger.SeatId
INNER JOIN Section ON AirplaneSeat.SectionId = Section.SectionId
INNER JOIN (Select FlightBookingId, sum(ExtraCost) as SumExtra from Extracost Group by FlightBookingId) as ExtraCost
ON ExtraCost.FlightBookingId=FlightBooking.FlightBookingId
INNER JOIN (Select FlightBookingId, sum(Price) as SumLuggage from Luggage Group by FlightBookingId) as Luggage
ON Luggage.FlightBookingId=FlightBooking.FlightBookingId
Are you sure that you have multiple records that match a single booking id?
If not, you can dispense with the sum():
SET FlightBooking.TotalCost = (Section.PriceInflux+Route.RoutePrice+Luggage.Price+SportsEquipment.SportsEquipmentPrice+Insurance.Price+CarHirePrice.TotalPrice)
If not, you'll need to pre-aggregate the tables that could generate multiple rows. In fact, you need to do this anyway to get a valid result (Cartesian products generated by joins will throw off the over sum).
many different possibilities for using aggregate funtion with update and inner join
UPDATE flight
SET flight.TotalCost = t.sumPrice
FROM FlightBooking AS flight
INNER JOIN
(
SELECT SUM(Section.PriceInflux+Route.RoutePrice+Luggage.Price+SportsEquipment.SportsEquipmentPrice+Insurance.Price+CarHirePrice.TotalPrice)) as sumPrice
FROM Passenger ON Passenger.FlightBookingId=flight.FlightBookingId
INNER JOIN AirplaneSeat ON AirplaneSeat.AirplaneSeatId = Passenger.SeatId
INNER JOIN Section ON AirplaneSeat.SectionId = Section.SectionId
INNER JOIN ExtraCost ON ExtraCost.FlightBookingId=flight.FlightBookingId
INNER JOIN Luggage ON Luggage.LuggageId = ExtraCost.LuggageId
INNER JOIN SportsEquipment ON ExtraCost.SportsEquipmentId=SportsEquipment.SportsEquipmentId
INNER JOIN Insurance ON ExtraCost.InsuranceId = Insurance.InsuranceId
INNER JOIN CarHirePrice ON CarHirePrice.CarHirePriceId= ExtraCost.CarHirePriceId
INNER JOIN Route ON flight.RouteId = Route.RouteId
) t
WHERE flight.bookingID = 1
also have a look to this examples
PC #PauloSantos and #OMGPonieshttps://stackoverflow.com/a/2009981/4426282

MySQL - #1066 - Not unique table/alias: 'components' with multiple inner joins

I have this query and I am getting error #1066 - Not unique table/alias: 'components'. What seems to be the issue?
SELECT COUNT(*) FROM `products`, `components`, `tradeNames`
INNER JOIN `componentsMap` ON componentsMap.product_id = product.id
INNER JOIN `components` ON componentsMap.component_id = components.id
INNER JOIN `tradeNamesMap` ON .tradeNamesMap.product_id = products.id
INNER JOIN `tradeNames` ON tradeNamesMap.tradeName_id = tradeNames.id
WHERE (((((LOWER(inci) LIKE '%abies%')
OR (trade_name.LOWER(name) LIKE '%abies%'))
OR (components.LOWER(no_cas)='abies'))
OR (components.LOWER(no_einecs)='abies'))
OR (components.LOWER(name)='abies'))
AND (`published`=1)
ORDER BY `trade_name`.`name` DESC
You don't need to list the tables before the INNER JOINs. In fact, simply don't ever use commas in the FROM clause. So:
SELECT COUNT(*)
FROM `products`
INNER JOIN `componentsMap` ON componentsMap.product_id = product.id
INNER JOIN `components` ON componentsMap.component_id = components.id
INNER JOIN `tradeNamesMap` ON tradeNamesMap.product_id = products.id
INNER JOIN `tradeNames` ON tradeNamesMap.tradeName_id = tradeNames.id
WHERE (((((LOWER(inci) LIKE '%abies%')
OR (trade_name.LOWER(name) LIKE '%abies%'))
OR (components.LOWER(no_cas)='abies'))
OR (components.LOWER(no_einecs)='abies'))
OR (components.LOWER(name)='abies'))
AND (`published`=1)
ORDER BY `trade_name`.`name` DESC;
The above query only returns one row because of the COUNT(). The order by suggests that you actually want this information for each trade_name.name. If so, you need a GROUP BY:
SELECT tn.name, COUNT(*)
FROM `products` p INNER JOIN
`componentsMap cm
ON cm.product_id = p.id INNER JOIN
`components` c
ON cm.component_id = c.id INNER JOIN
`tradeNamesMap` tnm
ON tnm.product_id = p.id INNER JOIN
`tradeNames` tn
ON tnm.tradeName_id = tn.id
WHERE ((LOWER(inci) LIKE '%abies%') OR
(tn.LOWER(name) LIKE '%abies%') OR
(c.LOWER(no_cas)='abies') OR
(c.LOWER(no_einecs)='abies') OR
(c.LOWER(name)='abies')
) AND
(`published` = 1)
GROUP BY tn.name
ORDER BY tn.`name` DESC
INNER JOIN `[components]` ON componentsMap.component_id = components.id
AND
SELECT COUNT(*) FROM `products`, [`components`], `tradeNames`
Two components are there.
Just guessing, and untested, but I suspect that something like this would do what you're after...
SELECT n.name
, COUNT(*)
FROM products p
JOIN componentsMap pc
ON pc.product_id = p.id
JOIN components c
ON c.id = pc.component_id
JOIN tradeNamesMap pn
ON pn.product_id = p.id
JOIN tradeNames n
ON n.id = pn.tradeName_id
WHERE
( inci LIKE '%abies%'
OR n.name LIKE '%abies%'
OR 'abies' IN (c.no_cas,c.no_einecs,c.name)
)
AND published = 1
GROUP
BY n.name
ORDER
BY n.name DESC

error mysql query with inner join

select simplex_comunes.cod_color_piel.descripcion as cod_color_piel, simplex_comunes.cod_sexo.descripcion as cod_sexo, count(*)
from simplex_comunes.cod_color_piel,simplex_comunes.cod_sexo
inner join simplex_ch.dat_trabajadores on simplex_ch.dat_trabajadores.id_color_piel = simplex_comunes.cod_color_piel.codigo
inner join simplex_ch.dat_trabajadores on simplex_comunes.cod_sexo.codigo = simplex_ch.dat_trabajadores.id_sexo
group by simplex_comunes.cod_color_piel.descripcion,simplex_comunes.cod_sexo.descripcion
the error is Not unique table/alias: 'dat_trabajadores',
Please help, thanks!!!
I haven't checked if your query is "intelligent" or not, but you have to use aliases as you use twice dat_trabajadores in your query.
You have to tell MySQL which table you use in your JOIN.
select simplex_comunes.cod_color_piel.descripcion as cod_color_piel, simplex_comunes.cod_sexo.descripcion as cod_sexo, count(*)
from simplex_comunes.cod_color_piel,simplex_comunes.cod_sexo
inner join simplex_ch.dat_trabajadores tr1 on simplex_ch.tr1.id_color_piel = simplex_comunes.cod_color_piel.codigo
inner join simplex_ch.dat_trabajadores tr2 on simplex_comunes.cod_sexo.codigo = simplex_ch.tr2.id_sexo
group by simplex_comunes.cod_color_piel.descripcion,simplex_comunes.cod_sexo.descripcion
you have two same aliases in your query.
rename them differently
select simplex_comunes.cod_color_piel.descripcion as descripcion,
simplex_comunes.cod_sexo.descripcion as cod_sexo_descripcion,
count(*)
from simplex_comunes.cod_color_piel,simplex_comunes.cod_sexo
inner join simplex_ch.dat_trabajadores t1 on t1.id_color_piel = simplex_comunes.cod_color_piel.codigo
inner join simplex_ch.dat_trabajadores t2 on simplex_comunes.cod_sexo.codigo = t2.id_sexo
group by simplex_comunes.cod_color_piel.descripcion,simplex_comunes.cod_sexo.descripcion