Mysql: WHERE not working in subquery? - mysql

I'm trying to get the WHERE part of my subquery to work below. I can see that 'where event_id=..' is ambiguous because the parent query is looking at the same table.
Is it even possible to have a WHERE in a same-table subquery?
UPDATE tickets SET tickets.ticket_number = (
SELECT max_ticket
FROM (
SELECT (MAX(ticket_number)+1) AS max_ticket
FROM tickets
WHERE event_id=10045
)
AS sub_table
)
WHERE ticket_id=68
Any help really appreciated.

Possibly try it as a join
UPDATE tickets a
INNER JOIN
(
SELECT (MAX(ticket_number)+1) AS max_ticket
FROM tickets
WHERE event_id = 10045
) b
SET a.ticket_number = b.max_ticket
WHERE a.ticket_id = 68

Related

Subquery for SQL

I need assistance in joining the two query statements together using subquery. I am confused on how I can combine the two together. I appreciate the help.
SELECT * FROM MEDICAL_PROCEDURE
JOIN PROCEDURE_CATEGORY ON medical_procedure.procedure_category_id = PROCEDURE_CATEGORY.PROCEDURE_CATEGORY_ID;
SELECT
Medical_procedure.medical_procedure_id,
COUNT(procedure_tool_supply.medical_procedure_id) AS Supply_Needed
FROM Procedure_tool_supply
JOIN Medical_Procedure on Procedure_tool_supply.medical_procedure_id = Medical_procedure.medical_procedure_id
GROUP BY Procedure_tool_supply.medical_procedure_id
HAVING COUNT(Procedure_tool_supply.medical_procedure_id) < 3;
Can't really test without test data, but this should work. Hopefully I figured out correctly what you're trying to do:
SELECT *
FROM
MEDICAL_PROCEDURE P
JOIN PROCEDURE_CATEGORY C ON
P.procedure_category_id = C.PROCEDURE_CATEGORY_ID
cross apply (
SELECT
COUNT(T.medical_procedure_id) AS Supply_Needed
FROM
Procedure_tool_supply T
where
T.medical_procedure_id = P.medical_procedure_id
GROUP BY
T.medical_procedure_id
HAVING
COUNT(T.medical_procedure_id) < 3
) T
It's not clear what you are trying to achieve. But if your intent is to include the derived Supply_Needed column from the second query on each row from the first query, and to restrict the rows returned to those that have a medical_procedure_id value returned by the second query, then...
you could do something like this:
SELECT mp.*
, pc.*
, ct.Supply_Needed
FROM MEDICAL_PROCEDURE mp
JOIN PROCEDURE_CATEGORY pc
ON mp.procedure_category_id = pc.PROCEDURE_CATEGORY_ID
JOIN ( SELECT pr.medical_procedure_id
, COUNT(ts.medical_procedure_id) AS Supply_Needed
FROM Procedure_tool_supply ts
JOIN Medical_Procedure pr
ON ts.medical_procedure_id = pr.medical_procedure_id
GROUP BY ts.medical_procedure_id
HAVING COUNT(ts.medical_procedure_id) < 3
) ct
ON ct.medical_procedure_id = mp.medical_procedure_id

MySQL Update with Subquery

I've got an annoying issue with an update query I'm trying to get working... The following statement SHOULD update channels.media_view_count to the result of the subquery (for all channels).
UPDATE channels c
SET c.media_view_count = (
SELECT SUM(t.view_count)
FROM (
SELECT DISTINCT m.viewkey, m.view_count
FROM media m
INNER JOIN participants p ON m.id = p.medium_id
WHERE p.user_id = c.id AND m.is_viewable = 1
AND (p.pending = 0)
) AS t
);
The subquery works fine independently (when specifying an actual id for c.id, like 47778 or whatever), but when I execute this statement, I get:
ERROR 1054 (42S22): Unknown column 'c.id' in 'where clause'
I thought I would be able to access the channels table (aliased as c) from within the subquery? Am I missing something or am I totally wrong here?
Any and all help is appreciated :)
Thanks,
Jeff
UPDATE channels c, (
SELECT t.user_id, SUM(t.view_count) cnt
FROM (
SELECT DISTINCT p.user_id, m.viewkey, m.view_count
FROM media m
INNER JOIN participants p ON m.id = p.medium_id
WHERE m.is_viewable = 1
AND (p.pending = 0)
) AS t GROUP BY t.user_id ) temp
SET c.media_view_count = temp.cnt
WHERE c.id = temp.user_id
Try like this... Did not test it though :) ..
Conceptually, it should work

MySQL update value from the same table with count

What I want to do is to set every patient its unique patient code which starts with 1 and it's not based on row id. Id only specifies order. Something like this:
patient_id patient_code
2 1
3 2
4 3
This is my query:
UPDATE patients p1
SET p1.patient_code = (
SELECT COUNT( * )
FROM patients p2
WHERE p2.patient_id <= p1.patient_id
)
But it is throwing error:
#1093 - You can't specify target table 'p1' for update in FROM clause
I found this thread: Mysql error 1093 - Can't specify target table for update in FROM clause.But I don't know how to apply approved answer this to work with subquery WHERE which is necessary for COUNT.
UPDATE
patients AS p
JOIN
( SELECT
p1.patient_id
, COUNT(*) AS cnt
FROM
patients AS p1
JOIN
patients AS p2
ON p2.patient_id <= p1.patient_id
GROUP BY
p1.patient_id
) AS g
ON g.patient_id = p.patient_id
SET
p.patient_code = g.cnt ;
I found working solution, but this is just workaround:
SET #code=0;
UPDATE patients SET patient_code = (SELECT #code:=#code+1 AS code)
Try this,
UPDATE patients p1 INNER JOIN
(
SELECT COUNT(*) as count,patient_id
FROM patients
group by patient_id
)p2
SET p1.patient_code=p2.count
WHERE p2.patient_id <= p1.patient_id
SQL_LIVE_DEMO
Thanks to Mari's answer I found a solution to my similar problem. But I wanted to add a bit of an explanation which for me at first wasn't too clear from his answer.
What I wanted to do would have been as simple as the following:
UPDATE my_comments AS c
SET c.comment_responses = (
SELECT COUNT(c1.*) FROM my_comments AS c1
WHERE c.uid = c.parent_uid
);
Thanks to Mari I then found the solution on how to achieve this without running into the error You can't specify target table 'p1' for update in FROM clause:
UPDATE my_comments AS c
INNER JOIN (
SELECT c1.parent_uid, COUNT(*) AS cnt
FROM my_comments AS c1
WHERE c1.parent_uid <> 0
GROUP BY c1.parent_uid
) AS c2
SET c.comment_responses = c2.cnt
WHERE c2.parent_uid = c.uid;
My problems before getting to this solution were 2:
the parent_uid field doesn't always contain an id of a parent which is why I added the WHERE statement in the inner join
I didn't quite understand why I would need the GROUP BY until I executed the SELECT statement on it's own and the answer is: because COUNT groups the result and really counts everything. In order to prevent this behavior the GROUP BY is needed. In my case I didn't have to group it by uid though but the parent_uid to get the correct count. If I grouped it by uid the COUNT would always be 1 but the parent_uid existed multiple times in the result. I suggest you check the SELECT statement on it's own to check if it's the result you expect before you execute the full UPDATE statement.

Error (1093):You cant update target table for update in FROM Clause

This is the select statement which i have got the correct answer:
select s_billing_cycle.Billing_cycle from s_billing_cycle
join o_daily_lcsgeneration_copy on o_daily_lcsgeneration_copy.Location=s_billing_cycle.Location where o_daily_lcsgeneration_copy.Date between s_billing_cycle.From_Date and s_billing_cycle.To_Date
while updating the same query into another table i couldnt do that using update query getting :
You cant update target table "o_daily_lcsgeneration_copy" for update in FROM Clause
the query i have used is :
update o_daily_lcsgeneration_copy set o_daily_lcsgeneration_copy.Billing_cycle = (select s_billing_cycle.Billing_cycle from s_billing_cycle join o_daily_lcsgeneration_copy on o_daily_lcsgeneration_copy.Location=s_billing_cycle.Location where o_daily_lcsgeneration_copy.Date between s_billing_cycle.From_Date and s_billing_cycle.To_Date)
Help me !!!
wrap it in a subquery (thus creating temporary table)
UPDATE o_daily_lcsgeneration_copy
SET o_daily_lcsgeneration_copy.Billing_cycle =
(
SELECT Billing_cycle
FROM
(
SELECT s_billing_cycle.Billing_cycle
FROM s_billing_cycle
INNER JOIN o_daily_lcsgeneration_copy
ON o_daily_lcsgeneration_copy.Location = s_billing_cycle.Location
WHERE o_daily_lcsgeneration_copy.DATE BETWEEN s_billing_cycle.From_Date
AND s_billing_cycle.To_Date
) s
)
or JOIN the tables
UPDATE o_daily_lcsgeneration_copy a
INNER JOIN s_billing_cycle b
ON a.Location = b.Location
SET a.Billing_cycle = b.Billing_cycle
WHERE a.DATE BETWEEN b.From_Date AND b.To_Date

mysql update query with sub query

Can anyone see what is wrong with the below query?
When I run it I get:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use
near 'a where a.CompetitionID = Competition.CompetitionID' at line 8
Update Competition
Set Competition.NumberOfTeams =
(
SELECT count(*) as NumberOfTeams
FROM PicksPoints
where UserCompetitionID is not NULL
group by CompetitionID
) a
where a.CompetitionID = Competition.CompetitionID
The main issue is that the inner query cannot be related to your where clause on the outer update statement, because the where filter applies first to the table being updated before the inner subquery even executes. The typical way to handle a situation like this is a multi-table update.
Update
Competition as C
inner join (
select CompetitionId, count(*) as NumberOfTeams
from PicksPoints as p
where UserCompetitionID is not NULL
group by CompetitionID
) as A on C.CompetitionID = A.CompetitionID
set C.NumberOfTeams = A.NumberOfTeams
Demo: http://www.sqlfiddle.com/#!2/a74f3/1
Thanks, I didn't have the idea of an UPDATE with INNER JOIN.
In the original query, the mistake was to name the subquery, which must return a value and can't therefore be aliased.
UPDATE Competition
SET Competition.NumberOfTeams =
(SELECT count(*) -- no column alias
FROM PicksPoints
WHERE UserCompetitionID is not NULL
-- put the join condition INSIDE the subquery :
AND CompetitionID = Competition.CompetitionID
group by CompetitionID
) -- no table alias
should do the trick for every record of Competition.
To be noticed :
The effect is NOT EXACTLY the same as the query proposed by mellamokb, which won't update Competition records with no corresponding PickPoints.
Since SELECT id, COUNT(*) GROUP BY id will only count for existing values of ids,
whereas a SELECT COUNT(*) will always return a value, being 0 if no records are selected.
This may, or may not, be a problem for you.
0-aware version of mellamokb query would be :
Update Competition as C
LEFT join (
select CompetitionId, count(*) as NumberOfTeams
from PicksPoints as p
where UserCompetitionID is not NULL
group by CompetitionID
) as A on C.CompetitionID = A.CompetitionID
set C.NumberOfTeams = IFNULL(A.NumberOfTeams, 0)
In other words, if no corresponding PickPoints are found, set Competition.NumberOfTeams to zero.
For the impatient:
UPDATE target AS t
INNER JOIN (
SELECT s.id, COUNT(*) AS count
FROM source_grouped AS s
-- WHERE s.custom_condition IS (true)
GROUP BY s.id
) AS aggregate ON aggregate.id = t.id
SET t.count = aggregate.count
That's #mellamokb's answer, as above, reduced to the max.
You can check your eav_attributes table to find the relevant attribute IDs for each image role, such as;
Then you can use those to set whichever role to any other role for all products like so;
UPDATE catalog_product_entity_varchar AS `v` INNER JOIN (SELECT `value`,`entity_id` FROM `catalog_product_entity_varchar` WHERE `attribute_id`=86) AS `j` ON `j`.`entity_id`=`v`.entity_id SET `v`.`value`=j.`value` WHERE `v`.attribute_id = 85 AND `v`.`entity_id`=`j`.`entity_id`
The above will set all your 'base' roles to the 'small' image of the same product.