UPDATE VALUE IN MYSQL MARIA DB WITH JOIN - mysql

I am trying to change the value of a column table with a sum function, this is my code:
For example
c.total = (10-2-3) - (3)
c.total = 2
update tabC c
JOIN tabB b ON b.c_id = c.id
set c.total = (c.v1 - c.v2 - c.v3) - IF(sum(b.payment) is not null, sum(b.payment), 0)
where c.id= 983;
but I get the following error:
ERROR 1111 (HY000): Invalid use of group function
I think the error is sum, but how can I solve that?
Thanls in advance

You need to join with a subquery that uses GROUP BY.
UPDATE tabC c
LEFT JOIN (
SELECT c_id, SUM(payment) AS total_payment
FROM tabB
GROUP BY c_id) AS b ON b.c_id = c.id
SET c.total = (c.v1 - c.v2 - c.v3) - IFNULL(b.total_payment, 0)
WHERE c.id = 983

You should usee a nested subquery whit aggregated resutl for join
update tabC c
JOIN (
select c_id, ifnull(sum(payment),0) tot_payment
from tabB
group by c_id
) b ON b.c_id = c.id
set c.total = (c.v1 - c.v2 - c.v3) - b.tot_payment
where c.id= 983;

Related

SQL UPDATE TABLE from SELECT query from other tables

I have bd hf3 and 5 tables there:
active_preset with columns (id , preset_id)
preset with columns (id , birja_id, trend_id, fractal, interval_up)
birja with columns (id , name)
trend with columns (id , name)
uq_active_preset with columns (id , birja, trend, fractal, interval_up)
In table preset I have a few records. Some of them are in table active_preset by foreign key preset_id. In table active_preset a few records exist once , a few more than once.
I need to update table uq_active_preset with records from table active_preset disregarding repetitions of records if they are present.
I did query from active_preset and it works good:
SELECT
b.name AS birja, p.fractal AS fractal , tre.name AS trend, p.interval_up AS interval_up
FROM hf3.active_preset AS ap
INNER JOIN hf3.preset AS p on p.id = ap.preset_id
INNER JOIN hf3.birja AS b on b.id = p.birja_id
INNER JOIN hf3.trend AS tre on tre.id = p.trend_id
GROUP BY b.name, p.fractal, tre.name, p.interval_up
HAVING COUNT(*) >= 1
But I don't know how to update uq_active_preset
I tried this and it returns syntax error:1064 :
UPDATE hf3.uq_active_preset uap SET
uap.birja = st.birja ,
uap.fractal = st.fractal,
uap.trend = st.trend,
uap.interval_up = st.interval_up,
FROM (SELECT b.name AS birja, p.fractal AS fractal , tre.name AS trend, p.interval_up AS interval_up
from hf3.active_preset AS ap
INNER JOIN hf3.preset AS p on p.id = ap.preset_id
INNER JOIN hf3.birja AS b on b.id = p.birja_id
INNER JOIN hf3.trend AS tre on tre.id = p.trend_id
GROUP BY b.name, p.fractal, tre.name, p.interval_up
HAVING COUNT(*) >= 1
) st
when you make an update using from is like you join the updated table with your query result. So, you need also a where statement in order to tell where those two are connected. Also, don't use alias of your updated table on set statement.
You need something like that:
UPDATE hf3.uq_active_preset uap SET birja=st.birja,fractal=st.fractal,trend=st.trend,interval_up=st.interval_up
FROM (SELECT b.name AS birja, p.fractal AS fractal , tre.name AS trend, p.interval_up AS interval_up
from hf3.active_preset AS ap
INNER JOIN hf3.preset AS p on p.id = ap.preset_id
INNER JOIN hf3.birja AS b on b.id = p.birja_id
INNER JOIN hf3.trend AS tre on tre.id = p.trend_id
GROUP BY b.name, p.fractal, tre.name, p.interval_up
HAVING COUNT(*) >= 1
) st
where uap.fkey=st.fkey

Simplified SQL Query

Currently we have to run the following SQL Query to find all customers that have not been assigned access to a downloadable product.
SELECT c.entity_id as customer_id, dp.purchased_id as purchased_id
FROM magento_dev.sales_order as so
JOIN magento_dev.sales_order_address as soa on so.entity_id = soa.parent_id
JOIN magento_dev.customer_entity as c on c.email = soa.shipping_email
JOIN magento_dev.downloadable_link_purchased as dp on so.increment_id = dp.order_increment_id
where
so.customer_id = 12345 and
so.created_at > '2021-04-01' and
soa.shipping_email is not null and
dp.customer_id != c.entity_id
;
Which produces this:
customer_id purchased_id
99999 55555
Then with the results, we manually have to go through, and for each customer_id, and purchase_id run the following query:
UPDATE `magento_dev`.`downloadable_link_purchased` SET `customer_id` = '99999' WHERE (`purchased_id` = '55555');
So for the SQL Ninja's, any suggestions on how to make this a single query that finds the mismatched assignments and then does the update/insert at once?
Just put all the JOINs in the UPDATE query.
UPDATE `magento_dev`.`downloadable_link_purchased` AS dp1
JOIN magento_dev.sales_order as so
JOIN magento_dev.sales_order_address as soa on so.entity_id = soa.parent_id
JOIN magento_dev.customer_entity as c on c.email = soa.shipping_email
JOIN magento_dev.downloadable_link_purchased as dp
ON so.increment_id = dp.order_increment_id
AND dp.customer_id != c.entity_id
AND dp1.purchased_id = dp.purchased_id
SET dp1.customer_id = c.entity_id
where
so.customer_id = 12345 and
so.created_at > '2021-04-01' and
soa.shipping_email is not null
Can be done like sub query and join with the table which should be updated,
UPDATE
magento_dev.downloadable_link_purchased F
JOIN
(SELECT c.entity_id as customer_id, dp.purchased_id as purchased_id
FROM magento_dev.sales_order as so
JOIN magento_dev.sales_order_address as soa on so.entity_id = soa.parent_id
JOIN magento_dev.customer_entity as c on c.email = soa.shipping_email
JOIN magento_dev.downloadable_link_purchased as dp on so.increment_id = dp.order_increment_id
WHERE
so.customer_id = 12345 and
so.created_at > '2021-04-01' and
soa.shipping_email is not null and
dp.customer_id != c.entity_id) S
ON F.purchased_id = S.purchased_id
SET F.customer_id = S.customer_id;

MYSQL, grouping with multiple columns

I have two tables. Sample Data Query:
cmadjprice:
select symbol,close,timestamp from cmadjprice;
ABCD,815.9,2014-10-31
ABCD,808.85,2014-11-03
ABCD,797.4,2014-11-05
ABCD,776.55,2014-11-07
ABCD,800.85,2014-11-10
ABCD,808.9,2014-11-11
ABCD,826.8,2014-11-12
ABCD,856.45,2014-11-13
ABCD,856.65,2014-11-14
BB03 table output sample query
select symbol,enter_dt,enter_price,exit_dt,exit_price from bb03 ;
ABCD,2014-10-31,815.90,2018-07-27,1073.60
am looking for maximum closing price with same date.
select a.symbol, max(a.close) ,a.timestamp from cmadjprice a
inner join BB03 b on a.symbol = b.symbol
where a.timestamp between b.enter_dt and b.exit_dt
group by a.symbol,a.timestamp;
am not getting output? Please help on this
Expecting output
ABCD,2014-10-31,815.90,2018-07-27,1073.60,856.65,2014-11-14;
I think this is what you need:
Note that this may return more than one record in case if the maximum close value appeared more than once throughout the sequence of timestamps related to a given symbol
select c.symbol, c.maxval, d.timestamp from
(
select
a.symbol,
max(a.close) as maxval
from
cmadjprice a
inner join BB03 b
on a.symbol = b.symbol
where a.timestamp between b.enter_dt and b.exit_dt
group by a.symbol
) c
inner join
cmadjprice d
on c.symbol = d.symbol and c.maxval = d.close
;
Try below :
select a.symbol, max(cast(a.close as DECIMAL(5,2))) from cmadjprice a
inner join BB03 b on a.symbol = b.symbol
where a.timestamp between b.enter_dt and b.exit_dt
group by a.symbol;

Trying to add one last SUM() column to my query in SQL Server 2008

I have the first query which is producing correct results. What I need is I need to add the sum of values as a last column grouped by surveyid. I can't insert Sum(c.value) into the first query because it is an aggregate function. I have the correct query as my second query below. I know there's pivot functionality but not sure if it can be used here. I do realize that there will be repetition but that's okay.
'first query
SELECT
A.PATIENTID, B.STUDENTNUMBER, c.surveyid,
convert(varchar, A.CreatedDate, 107),
C.QuestionID, C.Value, D.Question
FROM
dbo.Survey A, dbo.Patient B, [dbo].[SurveyQuestionAnswer] C, [dbo].[LookupQuestions] D
WHERE
A.PATIENTID = B.ID
and c.SurveyID = A.ID
and c.QuestionID = d.ID
and c.questionid <> 10
ORDER BY
A.PATIENTID
'second query
select
c.surveyid,SUM(c.value) as scores
from
dbo.SurveyQuestionAnswer c
group by
c.SurveyID
order by
SurveyID '---not important
You can use SUM if you add the OVER clause. In this case:
SELECT
A.PATIENTID, B.STUDENTNUMBER, c.surveyid,
convert(varchar, A.CreatedDate, 107),
C.QuestionID, C.Value, D.Question,
SUM(c.Value) OVER(PARTITION BY c.surveyid) scores
FROM
dbo.Survey A
INNER JOIN dbo.Patient B
ON A.PATIENTID = B.ID
INNER JOIN [dbo].[SurveyQuestionAnswer] C
ON c.SurveyID = A.ID
INNER JOIN [dbo].[LookupQuestions] D
ON c.QuestionID = d.ID
WHERE
c.questionid <> 10
ORDER BY
A.PATIENTID
You could use something like this:
SELECT
s.PATIENTID, p.STUDENTNUMBER, sqa.surveyid,
CONVERT(varchar, s.CreatedDate, 107),
sqa.QuestionID, sqa.Value, lq.Question,
Scores = (SELECT SUM(Value) FROM dbo.SurveyQuestionAnswer s2 WHERE s2.SurveyID = s.ID)
FROM
dbo.Survey s
INNER JOIN
dbo.Patient p ON s.PatientID = p.ID
INNER JOIN
[dbo].[SurveyQuestionAnswer] sqa ON sqa.SurveyID = s.ID
INNER JOIN
[dbo].[LookupQuestions] lq ON sqa.QuestionID = lq.ID
WHERE
sqa.questionid <> 10
ORDER BY
s.PATIENTID
By having a subquery with the SUM(...) you should be able to get that sum as a single value and you don't need to use any grouping function

MySQL Update table with sum value of another table

I have a query that I can't seem to manipulate to work in a SUM function in MySQL:
Here is what I want:
UPDATE account_seeds AS a
INNER JOIN b AS b ON b.accountID = a.accountID AND a.areaID = b.areaID
INNER JOIN b_seed AS s ON s.buildingID = b.buildingID
INNER JOIN seed_class AS c ON c.seedID = s.seedID
SET a.amount = a.amount + SUM(s.amount)
WHERE b.status='active' AND a.seedID = s.seedID
Now it obviously won't let me use the SUM in the update without separating it. I have tried joining select queries but can't quite get my head around it. The basic premise being that I have multiple buildings(rows) that has a seed value that will increase total seeds of that type in the area for a particular account. Without the sum it only updates one of the buildings that has a matching seed value
UPDATE
account_seeds AS a
INNER JOIN
( SELECT b.accountID, b.areaID, s.seedID
, SUM(s.amount) AS add_on
FROM b AS b
INNER JOIN b_seed AS s
ON s.buildingID = b.buildingID
INNER JOIN seed_class AS c
ON c.seedID = s.seedID
WHERE b.status = 'active'
GROUP BY b.accountID, b.areaID, s.seedID
) AS g
ON g.accountID = a.accountID
AND g.areaID = a.areaID
AND g.seedID = a.seedID
SET
a.amount = a.amount + g.add_on ;
Maybe you can use a nested query:
UPDATE account_seeds AS a
INNER JOIN b AS b ON b.accountID = a.accountID AND a.areaID = b.areaID
INNER JOIN b_seed AS s ON s.buildingID = b.buildingID
INNER JOIN seed_class AS c ON c.seedID = s.seedID
SET a.amount = a.amount + (SELECT SUM(amount) FROM b_seed)
WHERE b.status='active' AND a.seedID = s.seedID
Can you try that?