SQL noob trying to do update query with join - mysql

I’m trying to run an update query which I’ll run daily, unfortuntately I suck at SQL and have no clue what to do with the join functions. I keep getting invalid group error. I took the table names out
Managed to narrow down the issue (this is in SQLYog btw)
UPDATE CMCDAR
SET cmcdar.effective_exposure_in_global_currency = (mcdar.A_Rbalance - SUM(CASE
WHEN eps.fk_account_id = '90059' AND eps.sent_to_erp = '0' THEN (eps.transaction_amount) ELSE 0 END))
FROM eps
JOIN cmcdar ON eps.fk_customer_map_id = cmcdar.fk_customer_map_id
JOIN mcdar ON eps.fk_customer_map_id = mcdar.fk_customer_map_id
JOIN mcar ON eps.fk_customer_map_id = mcar.pk_customer_map_id
WHERE cmcdar.is_deleted = 0
AND mcar.is_deleted = 0
AND mcdar.is_deleted = 0
GROUP BY eps.fk_customer_map_id;
without Group by it returns it all as one bi
g row, with group by it fails. Interestingly with + rather than - in the sum it seems to seperate it even without group by. Any workarounds for group by?

Your syntax is off - see here:SQL Update with a Join
UPDATE
t1
SET
t1.c1 = t2.c2,
t1.c2 = expression,
...
FROM
t1
[INNER | LEFT] JOIN t2 ON join_predicate
WHERE
where_predicate;

I would assume move the join into from clause.
UPDATE cmcdar
SET effective_exposure_in_global_currency = (mcdar.A_Rbalance - SUM(CASE WHEN eps.fk_account_id =
'90059' AND eps.sent_to_erp = '0' THEN (eps.transaction_amount) ELSE 0 END))
from cmcdar
JOIN eps ON cmcdar.fk_customer_map_id = eps.fk_customer_map_id
JOIN mcar ON cmcdar.fk_customer_map_id = mcar.pk_customer_map_id
JOIN mcdar ON cmcdar.fk_customer_map_id = mcdar.fk_customer_map_id
WHERE cmcdar.is_deleted = 0
AND cmcdar.fk_customer_map_id = eps.fk_customer_map_id
AND mcar.is_deleted = 0
AND mcdar.is_deleted = 0
AND cmcdar.fk_account_id = '90059'
AND mcdar.fk_account_id = '90059';

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

SELECT Statement should return 0 when condition is not met

How can I make following MYSQL statment return 0 in case that the condition is not met.
(SELECT Sum(B.trblksize) AS RxData
FROM referencecoexistence_ber_lte B,
(SELECT C.*
FROM referencecoexistence C
WHERE `sw_ver` = '0.4'
AND `lte_n_frames` = '50'
AND `lte_rb` = '6'
AND `lte_mcs` = '11'
AND `lte_p_mw` = '6.000000e-03'
AND `lte_vmsf_type` = 'BS'
AND `lte_vmsf_subframes` = '8 9'
AND `wlan_mcs` = '5'
AND `wlan_p_mw` = '100'
AND `channel` = 'A330'
AND `lte_freq_hz` = '2403000000'
AND `wlan_freq_hz` = '2412000000'
AND `wlan_ieee` = '802.11n') AS TableX
WHERE TableX.id = B.id
AND B.ber = '0'
GROUP BY lte_dist_m)
The result is: Empty set (0.280 sec)
If the condition includes B.ber = '0' the expected output is:
A result with b.ber = 0 looks like:
RxData
416342016
433004544
...
In my case it would be sufficient if it simply returns one entry:
RxData
0
This statement is embedded in a larger statement that calculates some throughput.
Is it possible without executing the statement twice?
Here we'll change this to a LEFT OUTER JOIN. We will move the B.ber = '0' condition into the FROM clause, because with an outer join, this will give us different results than if the condition is in the WHERE clause.
SELECT Sum(B.trblksize) AS RxData
FROM (SELECT C.*
FROM referencecoexistence C
WHERE `sw_ver` = '0.4'
AND `lte_n_frames` = '50'
AND `lte_rb` = '6'
AND `lte_mcs` = '11'
AND `lte_p_mw` = '6.000000e-03'
AND `lte_vmsf_type` = 'BS'
AND `lte_vmsf_subframes` = '8 9'
AND `wlan_mcs` = '5'
AND `wlan_p_mw` = '100'
AND `channel` = 'A330'
AND `lte_freq_hz` = '2403000000'
AND `wlan_freq_hz` = '2412000000'
AND `wlan_ieee` = '802.11n') AS TableX
LEFT OUTER JOIN referencecoexistence_ber_lte B
ON TableX.id = B.id
AND B.ber = '0'
GROUP BY lte_dist_m
Now when B.ber is zero, it will act like an inner join. However, when B.ber is not zero, then the inner join result will be missing from the join, but the outer join will include the result with all the columns of the B table, but NULL for all the columns of the TableX table. So those records will have B.trblksize as NULL, and their sum will be NULL.
I solved the problem by simply using following approach
(SELECT SUM(IF(T_.BER =0,T_.TrBlkSize,0)) as RxData, Lte_Dist_m FROM
(ReferenceCoexistence WHERE <CONDITION LIST>) as X,
ReferenceCoexistence_BER_Lte as T_
WHERE X.ID = T_.ID GROUP BY Lte_Dist_m)

Query is running too slow?

I am writing a MySQL query with left join it giving me result in 28 seconds when I remove and condition with left join then it working in one second can any one tell me what is the issue in my query and how it will be modified?
select *
FROM regist_queue rq
left join appoint ap
on rq.token_number = ap.daily_ticket_no
and rq.LocationId = 15800
and ap.LocationId = 15800
and date(rq.QueueDate) = CURRENT_DATE()
and date(ap.dAppDate) = date(now())
left join patient pr
on ap.iPatID = pr.IPatID
left join gender ge
on pr.vGender = ge.iGenderID
where ifnull(ap.isDel,0) = 0
and ifnull(ap.is_referred,0) != 1
and (ap.LocationId = 15800 or rq.LocationId = 15800 )
order by rq.token_number asc;
I also applied indexes on all searched parameters and where joins are applied.
Explain plan of query.
MySQL Query Plan:
Your purpose is not pretty clear to me. For an example in the join and rq.LocationId = 15800
and ap.LocationId = 15800
and in the where clause and (ap.LocationId = 15800 or rq.LocationId = 15800 )
what my suggestion is to have something like this.
in the left join rq.LocationId = ap.LocationId
and in the where clause ap.LocationId = 15800
it is hard to evaluate the performance without having the real data.
Use SQL with (nolock) in sql query
like :
select *
FROM regist_queue rq with (nolock)
left join appoint ap with (nolock)
on rq.token_number = ap.daily_ticket_no
and rq.LocationId = 15800
and ap.LocationId = 15800
and date(rq.QueueDate) = CURRENT_DATE()
and date(ap.dAppDate) = date(now())
left join patient pr with (nolock)
on ap.iPatID = pr.IPatID
left join gender ge with (nolock)
on pr.vGender = ge.iGenderID
where ifnull(ap.isDel,0) = 0
and ifnull(ap.is_referred,0) != 1
and (ap.LocationId = 15800 or rq.LocationId = 15800 )
order by rq.token_number asc;
it seems there is Cartesian join....
base on the three predicate starts with on .........,
i think the sql statement does not based on your real purpose...

subquery returns more than 1 value this is not permitted when the subquery follows

I don't know why my case code is having an error but when I execute it not using a parameter by replacing the #PersonId by 2 it runs well. I try to exchange2x the JOIN but I am still having an error. Anyone knows?.
case when ISNULL(dbo.EducationalBackground.SchoolId,'') = '' then
(Select a.SchoolName
from dbo.EducationalBackground as A INNER JOIN
dbo.PersonEducationalBackground as B on a.EducationalBackgroundId = b.EducationalBackgroundId INNER JOIN
dbo.EducationLevel as C on a.EducationalLevelId = c.EducationLevelId
where b.PersonId = #PersonId and a.EducationalLevelId in (2,3))
else (select dbo.school.SchooldName from dbo.School INNER JOIN dbo.EducationalBackground
ON dbo.School.SchoolId = dbo.EducationalBackground.SchoolId INNER JOIN
dbo.PersonEducationalBackground ON dbo.EducationalBackground.EducationalBackgroundId = dbo.PersonEducationalBackground.EducationalBackgroundId
where dbo.PersonEducationalBackground.PersonId = #PersonId)
Cheers. Thanks.

What would cause a UNION to take an excessive amount of time?

I have a statement that looks like:
QUERY A
UNION
QUERY B
ORDER BY SomeColumn
Query A and Query B each take a nominal amount of time to run, but when I put them in the UNION, it take 7-9 seconds which is unacceptable. In this case Query A returns 6 rows, Query B returns 7. So confusing...
I have absolutely no idea what would cause this, help would be much appreciated!
Here is an anonymized version of the script (I did not write this, so don't hate):
SELECT
'XXX' l_t,
s.p,
srst.c_b,
srd.a_d_f,
s.s_c,
sf.c_s,
srst.p_f,
s.s_r_i,
s.s_i,
s.s_d,
srd.m_s_d_l s_d,
srd.m_e_d_l e_d,
CASE WHEN (srs.s_s_t IS NOT NULL AND srs.s_s_t <> srs.s_e_t)
THEN 1 ELSE 0 END 's_f',
CASE WHEN (srs.c_s_t IS NOT NULL AND srs.c_s_t <> srs.c_e_t)
THEN 1 ELSE 0 END 'c_f',
r.r_i
FROM
t_s_r_d srd
INNER JOIN t_s s WITH (NOLOCK)
ON s.s_i = srd.s_i
INNER JOIN i_s_r(12345) r
ON r.r_i = srd.r_i
INNER JOIN i_s_s_f() sf
ON (sf.s_i = srd.s_i)
INNER JOIN t_s_r_s srst WITH (NOLOCK)
ON (srst.s_i = srd.s_i AND srst.r_i = srd.r_i )
LEFT OUTER JOIN t_s_r_s srs WITH (NOLOCK)
ON (srs.s_i = srd.s_i AND srs.r_i = srd.r_i)
WHERE
srst.d_f = 0
AND ((srd.m_s_d_l >= someval AND srd.m_s_d_l < someotherval)
OR
(srd.m_s_d_l <= someval AND srd.m_e_d_l > someotherval))
AND r.o_f = 0
AND r.i_f = 0
AND r.v_f = 1
AND r.g_i = 180
AND NOT EXISTS(SELECT * FROM t_c_r cdr WITH (NOLOCK) WHERE cdr.r_i = r.r_i)
UNION
SELECT
'XXX' l_t,
s.p,
srst.c_b,
srd.a_d_f,
s.s_c,
sf.c_s,
srst.p_f,
s.s_r_i,
s.s_i,
s.s_d,
srd.m_s_d_l s_d,
srd.m_e_d_l e_d,
CASE WHEN (srs.s_s_t IS NOT NULL AND srs.s_s_t <> srs.s_e_t)
THEN 1 ELSE 0 END 's_f',
CASE WHEN (srs.c_s_t IS NOT NULL AND srs.c_s_t <> srs.c_e_t)
THEN 1 ELSE 0 END 'c_f',
c.c_i
FROM
(t_s_r_d srd
INNER JOIN t_s s WITH (NOLOCK)
ON s.s_i = srd.s_i
INNER JOIN i_s_s_f() sf
ON (sf.s_i = srd.s_i)
LEFT OUTER JOIN t_s_r_s srs WITH (NOLOCK)
ON (srs.s_i = srd.s_i AND srs.r_i = srd.r_i)
INNER JOIN t_s_r_s srst WITH (NOLOCK)
ON (srst.s_i = srd.s_i AND srst.r_i = srd.r_i)),
i_s_c(12345) c
WHERE
srst.d_f = 0
AND ((srd.m_s_d_l >= someval AND srd.m_s_d_l < someotherval)
OR
(srd.m_s_d_l <= someval AND srd.m_e_d_l > someotherval))
AND c.o_f = 0
AND c.i_f = 0
AND c.v_f = 1
AND c.g_i = 180
AND EXISTS(SELECT * FROM t_c_r cr WITH (NOLOCK) WHERE cr.r_i = srd.r_i and
cr.c_i = c.c_i)
ORDER BY s_d
Because UNION removes duplicates it has to sort the whole data set first...try to use UNION ALL instead....it is much faster since it doesn't need to remove the dups
Turns out it was the old style ansii style joins in conjunction with the newer style explicit joins that were causing the lengthy return. Quite interesting, if anyone could provide a reason why that would be fantastic!