This is the query:
SELECT *
FROM square_achievements_achievements
JOIN square_achievements_achievement_counters ON square_achievements_achievement_counters.SAA_ID = square_achievements_achievements.SAA_ID
JOIN square_achievements_counters ON square_achievements_counters.SAC_ID = square_achievements_achievement_counters.SAC_ID
WHERE square_achievements_counters.eventObject = 'CommentEvent'
AND square_achievements_counters.eventType = 'add'
AND square_achievements_achievements.SAA_ID NOT IN
(
SELECT square_achievements_achievements.SAA_ID
FROM square_achievements_achievements
JOIN square_achievements_user_achievements ON square_achievements_user_achievements.SAA_ID = square_achievements_achievements.SAA_ID
WHERE square_achievements_user_achievements.UID = 83
)
If it's possible, would it be more efficient to write this query as a join? If so, how would it be rewritten?
SELECT a.*
FROM achievements a
JOIN achievement_counters ac
ON ac.saac_id = a.saa_id
JOIN counters c
ON c.sac_id = ac.sac_id
WHERE c.eventObject = 'CommentEvent'
AND c.eventType = 'add'
AND a.saa_id NOT IN
(
SELECT saa_id
FROM user_achievements
WHERE uid = 83
)
This is pretty good.
If you want joins, use this:
SELECT a.*
FROM achievements a
JOIN achievement_counters ac
ON ac.saac_id = a.saa_id
JOIN counters c
ON c.sac_id = ac.sac_id
LEFT JOIN
user_achievements ua
ON ua.uid = 83
AND ua.saa_id = a.saa_id
WHERE c.eventObject = 'CommentEvent'
AND c.eventType = 'add'
AND ua.saa_id IS NULL
I prefer to use correlation names to improve the readability of the code
Try this:
SELECT *
FROM square_achievements_achievements a
JOIN square_achievements_achievement_counters b ON b.SAAC_ID = a.SAA_ID
JOIN square_achievements_counters c ON c.SAC_ID = b.SAC_ID
JOIN square_achievements_user_achievements d on d.SAA_ID = a.SAA_ID
JOIN square_achievements_user_achievements u on d.SAA_ID = u.SAA_ID AND u.UID = 83
WHERE c.eventObject = 'CommentEvent'
AND a.eventType = 'add'
Related
I wrote a retrieve function in PostgreSQL. In JSON calling another object and I am getting a duplicate value so I added a distinct and run could not identify an equality operator for type JSON.
Here is my function:
return query
select(SELECT array_to_json(array_agg(row_to_json(resdt))) FROM
(select distinct vp.project_id,cvv.id as projid,vp.project_name,vp.description,vp.start_date,vp.end_date,vp.duration,
vp.label_id,vp.created_by,vp.company_id,vp.provider_name as client_name,vp.actual_end_date,
concat(vu.first_name,vu.last_name) as user_name,
--vt.name as company_name,vt.domain,
vu.email,
10 as chat_count,vp.project_start_time,vp.project_end_time,
vp.status as project_status,
(select array_to_json(array_agg(row_to_json(b))) FROM
(select vpr.project_id,vpr.project_name,vl.label_id,vl.label_name,vl.label_type
from public."VOfficeApp_projects" vpr
inner join public."VOfficeApp_project_labels" vpl on vpr.project_id = vpl.project_id
inner join public."VOfficeApp_labels" vl on vl.label_id = vpl.label_id
where vpr.company_id = 1047
and vpr.created_by = 3465
and vpr.project_id = vp.project_id
and vl.label_type ='p' )b)as label_name,
(select array_to_json(array_agg(row_to_json(b))) FROM
(select concat(u.first_name,u.last_name) as first_name,vpr.employee_id as id,
vpr.project_resource_id,u.email
from public."VOfficeApp_projects" pro
inner join public."VOfficeApp_project_resources" vpr on pro.project_id = vpr.project_id
inner join public."VOfficeApp_user" u on vpr.employee_id = u.id
where pro.company_id = 1047
and pro.created_by = 3465 and vpr.released_date is null
and pro.project_id = vp.project_id)b)as team_members
from public."VOfficeApp_projects" vp
inner join public."VOfficeApp_project_resources" vpr on vp.project_id = vpr.project_id
inner join public."VOfficeApp_user" vu on vu.id =vpr.employee_id
left join public."VOfficeApp_conversation" cvv on cvv.projtaskid = vp.project_id
where vp.company_id = 1047 and vpr.employee_id = 3465
and vp.status != 'Delete'
--order by vp.project_id desc
)resdt)as My_tasks;
I have the following query and would like to convert it to using a left outer join instead of a not in to see if it would run faster that way. It's currently taking this query about 40 seconds to run on our database. I'm not familiar enough with using outer joins for this type of thing to convert it myself.
select
c.contact_id as contact_id,
c.orgid as organization_id,
c.first_name as first_name,
c.last_name as last_name,
a.address_state as state
from cnx_contact as c
inner join cnx_address as a on c.home_address_uid = a.address_uid
where a.address_state = 'OH'
and (c.orgid = 45 or c.orgid = 55)
and c.contact_id NOT IN (
select pc.contact_id
from cnx_contact as c
inner join cnx_address as a on c.home_address_uid = a.address_uid
inner join cnx_contact_group_participant as gp on c.contact_id = gp.contact_id
inner join cnx_contact_participant_role as cr on gp.participant_role_uid = cr.participant_role_uid
inner join cnx_contact_group as cg on gp.group_uid = cg.group_uid
inner join cnx_contact_group_participant as pgp on cg.primary_participant_uid = pgp.participant_uid
inner join cnx_contact as pc on pgp.contact_id = pc.contact_id
where (c.orgid = 45 or c.orgid = 55)
and cr.name = 'Applicant'
);
select
c.columns
from cnx_contact as c
inner join cnx_address as a on c.home_address_uid = a.address_uid
LEFT JOIN
(Subquery goes here) x
ON x.contact _id = c.contact_id
where a.participant_state = 'OH'
and c.orgid IN(45,55)
and x.contact_id IS NULL;
i have a huge query:
SELECT stories.*
FROM stories stories
JOIN (SELECT tstories.uid
FROM stories tstories
JOIN tours_stories_mm mmt
ON tstories.uid = mmt.uid_foreign
JOIN tours tours
ON tours.uid = mmt.uid_local
JOIN tours_countries_rel tourcountryrel
ON tours.uid = tourcountryrel.tourid
JOIN countries tcountries
ON tcountries.uid = tourcountryrel.countryid
WHERE tcountries.uid = ?
AND tours.deleted = 0
AND tours.hidden = 0
AND tstories.deleted = 0
AND tstories.hidden = 0) as tourstories
JOIN (SELECT cstories.uid
FROM stories cstories
JOIN individualtourcomponents_stories_mm mmc
ON (cstories.uid = mmc.uid_foreign)
JOIN individualtourscomponents components
ON (components.uid = mmc.uid_local)
JOIN individualtourcomponents_countries_rel componentcountryrel
ON (components.uid = componentcountryrel.componentid)
JOIN countries ccountries
ON (ccountries.uid = componentcountryrel.countryid)
WHERE ccountries.uid = ?
AND components.deleted = 0
AND components.hidden = 0
AND cstories.deleted = 0
AND cstories.hidden = 0) as componentstories
WHERE stories.uid = componentstories.uid
OR stories.uid = tourstories.uid
GROUP BY stories.uid`
each of the subqueries work for themselves and if both subqueries have the same result, i get an result on the whole query. If only one subquery has a result i get nothing. Simplyfied it could be written like that:
SELECT stories.*
FROM stories
JOIN (SELECT * FROM table_a WHERE x=5) as table_a
JOIN (SELECT * form table_b where x=5) as table_b
WHERE stories.uid = table_a.uid OR stories.uid = table_b.uid
GROUP BY stories.uid
What am i doing wrong?
It seems like you should be using an OUTER JOIN instead of INNER JOIN to join your source tables.
Using the simplified query example, it might look like this:
SELECT stories.*
FROM stories
LEFT OUTER JOIN (SELECT * FROM table_a WHERE x=5) as table_a
ON stories.uid = table_a.uid
LEFT OUTER JOIN (SELECT * form table_b where x=5) as table_b
ON stories.uid = table_b.uid
GROUP BY stories.uid
UPDATE
Based on your comment it sounds like you actually want to get the distinct union of the the two sub queries.
If that's the case, you could modify your original query like this:
(SELECT tstories.*
FROM stories tstories
JOIN tours_stories_mm mmt
ON tstories.uid = mmt.uid_foreign
JOIN tours tours
ON tours.uid = mmt.uid_local
JOIN tours_countries_rel tourcountryrel
ON tours.uid = tourcountryrel.tourid
JOIN countries tcountries
ON tcountries.uid = tourcountryrel.countryid
WHERE tcountries.uid = ?
AND tours.deleted = 0
AND tours.hidden = 0
AND tstories.deleted = 0
AND tstories.hidden = 0
)
UNION DISTINCT
(SELECT cstories.*
FROM stories cstories
JOIN individualtourcomponents_stories_mm mmc
ON (cstories.uid = mmc.uid_foreign)
JOIN individualtourscomponents components
ON (components.uid = mmc.uid_local)
JOIN individualtourcomponents_countries_rel componentcountryrel
ON (components.uid = componentcountryrel.componentid)
JOIN countries ccountries
ON (ccountries.uid = componentcountryrel.countryid)
WHERE ccountries.uid = ?
AND components.deleted = 0
AND components.hidden = 0
AND cstories.deleted = 0
AND cstories.hidden = 0
)
SELECT *
FROM members
WHERE memberid IN (SELECT follows.followingid
FROM follows
WHERE follows.memberid = '$memberid'
AND follows.followingid NOT IN (SELECT memberid
FROM userblock))
AND memberid NOT IN (SELECT blockmemberid
FROM userblock
WHERE memberid = '$memberid')
The query above is taking nearly 4 seconds to execute in MySQL and I want to know if anyone has any suggestions on how I might improve/optimize it to achieve a faster execution time?
Replace the in clauses with joins. I think the following captures the logic. Note that the not in turns into a left join with a condition in the where clause finding a non-match
SELECT m.*
FROM members m
follow f
on m.memberid = f.followingid and
f.memberid = $memberid left join
userblock ubf
on follows.followingid = ubf.memberid left join
userblock ub
on m.memberid = ub.blockmemberid and
ub.memberid = '$memberid'
where ub.blockmemberid is null and
ubf.memberid is null;
This looks similar but you have less nested queries.
SELECT *
FROM members m
WHERE EXIST (SELECT f.followingid
FROM follows f
WHERE f.memberid = '$memberid'
AND f.followingid = m.memberid)
AND NOT EXIST (SELECT u.blockmemberid
FROM userblock u
WHERE (m.memberid = '$memberid'
AND u.blockmemberid = m.memberid)
OR
(u.blockmemberid = m.memberid
AND u.memberid = m.memberid) )
This is the logic I reversed-engineered from your code without seeing tables.
SELECT m.*
FROM members m
INNER JOIN follows f ON f.followingid = m.memberid AND
f.memberid = '$memberid'
LEFT OUTER JOIN userblock ub1 ON f.followingid = ub1.memberid
LEFT OUTER JOIN userblock ub2 ON m.memberid = ub2.blockmemberid AND
ub2.memberid = '$memberid'
WHERE ub1.memberid IS NULL AND ub2.blockmemberid IS NULL
I've got the query below that's pulling data from a number of tables to create an update:
UPDATE en_inter.subscribers_data AS sd
inner join en_inter.list_subscribers AS ls on sd.subscriberid = ls.subscriberid
LEFT JOIN (
SELECT pd1.email_address,COUNT(pd1.email_address) AS NumDowns
FROM email.papr_down pd1
INNER JOIN email.papr_data pd2 on pd1.paper_id = pd2.id
INNER JOIN email.papr_subj ps on ps.id = pd2.subject
INNER JOIN email.papr_exam pe on pe.id = pd2.exam
INNER JOIN email.papr_levl pl on pl.id = pd2.level
WHERE pd2.exam = 1
and pd2.level = 4
GROUP BY email_address
) AS downs ON downs.email_address = ls.emailaddress
SET sd.data = ifnull(downs.NumDowns,1)
WHERE sd.fieldid = 33;
It works fine but when there are plenty of records in papr_down then it takes ages to process. Any ideas about how it can be optimized?
What I think is the join between the emailAddress is the issue here, you can try out with the join with the Id's.
If you provide us the screen shot of the below query ::
EXPLAIN Select * from
en_inter.subscribers_data AS sd
inner join en_inter.list_subscribers AS ls on sd.subscriberid = ls.subscriberid
LEFT JOIN (
SELECT pd1.email_address,COUNT(pd1.email_address) AS NumDowns
FROM email.papr_down pd1
INNER JOIN email.papr_data pd2 on pd1.paper_id = pd2.id
INNER JOIN email.papr_subj ps on ps.id = pd2.subject
INNER JOIN email.papr_exam pe on pe.id = pd2.exam
INNER JOIN email.papr_levl pl on pl.id = pd2.level
WHERE pd2.exam = 1
and pd2.level = 4
GROUP BY email_address
) AS downs ON downs.email_address = ls.emailaddress
WHERE sd.fieldid = 33
As I know we should use joins only for the columns which are preset in SELECT clause and for other joins we should implement using WHERE clause
Please try following query:
UPDATE en_inter.subscribers_data AS sd
inner join en_inter.list_subscribers AS ls
on sd.subscriberid = ls.subscriberid
LEFT JOIN (
SELECT pd1.email_address,COUNT(pd1.email_address) AS NumDowns
FROM email.papr_down AS pd1
INNER JOIN email.papr_data AS pd2 on pd1.paper_id = pd2.id
WHERE
email.papr_exam.id in (select exam from email.papr_data where exam = 1)
AND
email.papr_levl.id in (select level from email.papr_data where level = 4 )
AND
email.papr_subj.id in (select subject from email.papr_data)
GROUP BY email_address
) AS downs ON downs.email_address = ls.emailaddress
SET sd.data = ifnull(downs.NumDowns,1)
WHERE sd.fieldid = 33;
I can not execute this at my machine since i don't have the schema