how understand the relation between parent query and subquery in mysql? - mysql

Someone please explain the difference between parent query and sub query? How do I understand?
e.g:
SELECT
ra.ID id,
ra.ACCOUNT_ID accountId,
ef.REAL_NAME realName,
a.MOBILE mobile,
sps.`NAME` siteName,
ef.CREATE_TIME createTime,
a.`STATUS` status,
ra.`STATUS` siteStatus,
(
SELECT
aif.APPROVER_NAME
FROM
audit_info aif
WHERE
aif.TARGET_ID = a.ID AND af.AUDIT_TYPE=2
AND aif.CREATE_TIME = (
SELECT
MAX(af.CREATE_TIME)
FROM
audit_info af
WHERE
af.TARGET_ID = a.ID AND af.AUDIT_TYPE=2
)
) AS approverName
FROM
account a
INNER JOIN site_relation_account ra ON ra.ACCOUNT_ID = a.ID
INNER JOIN account_ext ef ON ra.ACCOUNT_ID = ef.ACCOUNT_ID
INNER JOIN service_provider_site sps ON sps.ID = ra.SITE_ID
LEFT JOIN audit_info af ON af.TARGET_ID = ef.ACCOUNT_ID
WHERE ra.ACCOUNT_TYPE = 2

Related

Mysql triple join error:Not unique table/alias: 'cushbu_mark_user_favorites'

I have 3 tables in my db
1)cushbu_users (id,first_name,last_name)
2)cushbu_art (id,user_id(FK cushbu_user),title,base_price etc...) -for store user arts
3)cushbu_mark_user_favorites (id,user_id(FK cushbu_user),art_id(FK cushbu_art)) -for marking favourite items
I want to fetch the all art items of a particular user favourited
with count of favourites each art (stored in cushbu_mark_usier_favorites table )
Here is my query
SELECT
cushbu_art.id AS art_id,
cushbu_art.title,
cushbu_art.base_price,
cushbu_art.image_name,
CONCAT(
cushbu_users.first_name,
' ',
cushbu_users.last_name
) AS artist_name,COUNT(cushbu_mark_user_favorites.art_id)
FROM
cushbu_art
JOIN cushbu_mark_user_favorites ON cushbu_mark_user_favorites.art_id = cushbu_art.id
JOIN cushbu_users ON cushbu_users.id = cushbu_art.artist_id
LEFT JOIN cushbu_mark_user_favorites ON cushbu_art.id=cushbu_mark_user_favorites.art_id
WHERE
cushbu_mark_user_favorites.user_id = 68
But i got Not unique table/alias: 'cushbu_mark_user_favorites' this join statement
LEFT JOIN cushbu_mark_user_favorites ON cushbu_art.id=cushbu_mark_user_favorites.art_id
UPDATE
SELECT
a.id AS art_id,
a.title,
a.base_price,
a.image_name,
CONCAT(
c.first_name,
' ',
c.last_name
) AS artist_name,COUNT(b.art_id)
FROM
cushbu_art a
JOIN cushbu_mark_user_favorites b ON b.art_id = a.id
JOIN cushbu_users c ON c.id = a.artist_id
LEFT JOIN b ON a.id=b.art_id
WHERE
b.user_id = 68
Try below query.
SELECT
cushbu_art.id AS art_id,
cushbu_art.title,
cushbu_art.image_name,
CONCAT(
cushbu_users.first_name,
' ',
cushbu_users.last_name
) AS artist_name , b.favorites_count as total_fav
FROM
cushbu_mark_user_favorites
LEFT JOIN cushbu_art ON cushbu_art.id=cushbu_mark_user_favorites.art_id
LEFT JOIN cushbu_users ON cushbu_users.id = cushbu_art.artist_id
LEFT JOIN (SELECT art_id,count(*) as favorites_count FROM cushbu_mark_user_favorites GROUP BY art_id) as b ON b.art_id=cushbu_art.id
WHERE cushbu_mark_user_favorites.user_id=1
GROUP BY cushbu_art.id
Hope this will helpful to you.

SQL INNER join take too long to execute

I have below sql query that take too long to execute, please there is an alternative for inner joins to resolve my issue?, because when I remove 3 or 4 joins the query is executed faster.
SELECT p.first_name, p.last_name, p.x, p.dob,'name', w.id_table1, w.type, w.stype, w.ploc, w.dat, w.created_at, av.item as table1_edge , av1.item as sdf ,av2.item as sd, av3.item as odor, av4.item as xz, av5.value as xxx , av9.item as cc, av10.item as cxz
FROM table1 w
INNER JOIN table2 a ON w.id_table1 = a.table1_id_table1
INNER JOIN table3 av ON a.id_table2 = av.id_table3 and av.sub_group = 'x1'
INNER JOIN table3 av1 ON a.id_table2 = av1.id_table3 and av1.sub_group = 'x2'
INNER JOIN table3 av2 ON a.id_table2 = av2.id_table3 and av2.sub_group = 'x3'
INNER JOIN table3 av3 ON a.id_table2 = av3.id_table3 and av3.sub_group = 'x4'
INNER JOIN table3 av4 ON a.id_table2 = av4.id_table3 and av4.sub_group = 'x5'
INNER JOIN table3 av5 ON a.id_table2 = av5.id_table3 and av5.sub_group = 'x6' and av6.item like 's%'
INNER JOIN table3 av6 ON a.id_table2 = av6.id_table3 and av6.sub_group = 'x7' and av6.item like 'x%'
INNER JOIN table3 av7 ON a.id_table2 = av7.id_table3 and av7.sub_group = 'x8' and av6.item like 'z%'
INNER JOIN table3 av8 ON a.id_table2 = av8.id_table3 and av8.sub_group = 'x9' and av6.item like 'y%'
INNER JOIN table3 av9 ON a.id_table2 = av9.id_table3 and av9.sub_group = 'x10'
INNER JOIN table3 av10 ON a.id_table2 = av10.id_table3 and av10.sub_group = 'x11'
INNER JOIN table0 p ON w.table0_id_table0 = p.id_table0
where w.created_at between '1991-12-09 00:00:00' and now() and user_id_user = 4
data:
table0
first_namelast_namedob...
table1id_table1 type stype ...
Have you tried to use subqueries instead for the inner joins that take longer to execute?
Example:
select a.id, b.id, c.id
from table a
inner join (
select id
from tableb
where b = 'x1'
) as b on b.id = a.id
inner join (
select id
from tablec
where c = 'x2'
) as c on c.id = a.id
Maybe you can make you query simpler like this:
SELECT p.first_name, p.last_name, p.x, p.dob,'name',
w.id_table1, w.type, w.secondary_type, w.primary_location,
w.onset, w.created_at, av.item,
IF(av.sub_group='x1', 1, 0) as val_x1,
IF(av.sub_group='x2', 1, 0) as val_x2,
IF(av.sub_group='x3', 1, 0) as val_x3,
..........
IF(av.sub_group='x11', 1, 0) as val_x11
FROM table1 w
INNER JOIN table2 a ON w.id_table1 = a.table1_id_table1
left join table3 av on a.id_table2 = av.id_table3
INNER JOIN table0 p ON w.table0_id_table0 = p.id_table0
where w.created_at between '1991-12-09 00:00:00'
and now() and user_id_user = 4
and ( (av.sub_group in ('x1', 'x2', 'x3', 'x4', 'x5', 'x10', 'x11'))
or (av.sub_group='x6' and av.item like 's%')
or (av.sub_group='x7' and av.item like 'x%')
or (av.sub_group='x8' and av.item like 'z%')
or (av.sub_group='x9' and av.item like 'y%')
)
We make just one JOIN with table table3 and move all conditions into where clause. With val_x1 .... val_x11 we can know which one value we have at av.item.
You seem to be storing things in an EAV format (entity-attribute-value). If you don't understand what this means, you can review the definitions on Wikipedia.
One solution is to use aggregation:
SELECT p.first_name, p.last_name, p.x, p.dob, 'name',
w.id_table1, w.type, w.secondary_type, w.primary_location,
w.onset, w.created_at,
MAX(CASE WHEN av.sub_group = 'x1' THEN av.item END) as table1_edge,
MAX(CASE WHEN av.sub_group = 'x1' THEN av.item END) as sdf,
. . .
FROM table1 w INNER JOIN
table2 a
ON w.id_table1 = a.table1_id_table1 INNER JOIN
table3 av
ON a.id_table2 = av.id_table3
WHERE av.sub_group IN ('x1', 'x2', . . . ) AND
w.created_at between '1991-12-09' and now() AND
user_id_user = 4
GROUP BY p.first_name, p.last_name, p.x, p.dob,
w.id_table1, w.type, w.secondary_type, w.primary_location, w.onset, w.created_at;
You also want appropriate indexes. I am guessing these are table1(user_id_user, created_at, id_table1) and table3(id_table3, sub_group, item).

mysql where not in to left outer join

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;

multiple table join to generate report counts

I am trying to generate a report that will display data from 3 tables as follows:
SELECT B.datepoll, B.clientID, B.badTerm, A.FullQuery,
B.badMessage, C.clientNAME, E.CURRENT_TERMS
FROM BadTerms AS B INNER JOIN
QueryTERMS AS A ON B.badTerm = A.QUERIES INNER JOIN
Clients AS C ON B.clientID = C.clientID INNER JOIN
(
SELECT CLIENTID,COUNT(QUERIES) AS CURRENT_TERMS FROM QueryTERMS WHERE
clientID = 'XXXXXX' GROUP BY CLIENTID) E ON
E.CLIENTID = A.CLIENTID
WHERE (CONVERT(VARCHAR(10), B.datepoll, 120) < CONVERT(VARCHAR(10), GETDATE(), 120))
AND (B.clientID = 'XXXXXX')
Basically what should be displayed is for a given datepoll, display all badTerms, fullQuery, badMessage, clientID, clientName and total terms. The clientID is common among all 3 tables and queries is common among BadTerms and QueryTerms.
I have everything fine except for the total count. It should only appear once and be the total queries in the QueryTerms table not the BadTerms table.
Any help appreciated.
Actually got it to work now:
SELECT B.datepoll, B.clientID, B.badTerm, A.FullQuery,
B.badMessage, C.clientNAME, E.CURRENT_TERMS
FROM BadTerms AS B INNER JOIN
QueryTERMS AS A ON B.badTerm = A.QUERIES INNER JOIN
Clients AS C ON B.clientID = C.clientID INNER JOIN
(
SELECT CLIENTID,COUNT(QUERIES) AS CURRENT_TERMS FROM QueryTERMS WHERE
clientID = 'XXXXXX' GROUP BY CLIENTID) E ON
E.CLIENTID = A.CLIENTID
WHERE (CONVERT(VARCHAR(10), B.datepoll, 120) < CONVERT(VARCHAR(10), GETDATE(), 120))
AND (B.clientID = 'XXXXXX')

slow query with joins

Please am having difficulty in optimizing this query. What am trying to achieve is to join about 8 tables, of which only about 3 of the tables contains large data (1.5m records). This query returns expected records but is taking 1min to run which is bad.
I know it can be optimized to perform far better, pls i need assistance from you experts. I have index on the fields used for join already.
SELECT topic_id,
topic_title,
unit_name_abbrev,
sch_name_abbrev,
picture_small_url AS thumbnail,
profile_pix_upload_path,
first_name,
last_name,
topic_poster,
topic_replies,
topic_views,
topic_last_post_time AS topic_post_time,
sch_sub_forum_id
FROM (_sch_forum_topics
INNER JOIN _users
ON ( _users.userid = _sch_forum_topics.topic_poster )
INNER JOIN _profile
ON _profile.userid = _users.userid
INNER JOIN _class
ON _users.classid = _class.classid
INNER JOIN _level
ON _class.level_id = _level.id
INNER JOIN _unit
ON _class.unitid = _unit.unitid
INNER JOIN _department
ON _unit.deptid = _department.deptid
INNER JOIN _faculty
ON _department.facid = _faculty.facid
INNER JOIN _university
ON _faculty.schid = _university.schid)
WHERE _sch_forum_topics.sch_sub_forum_id = 4
ORDER BY _sch_forum_topics.topic_last_post_time DESC
LIMIT 0, 15
Try to filter before making JOIN's.
SELECT topic_id,
topic_title,
unit_name_abbrev,
sch_name_abbrev,
picture_small_url AS thumbnail,
profile_pix_upload_path,
first_name,
last_name,
topic_poster,
topic_replies,
topic_views,
topic_last_post_time AS topic_post_time,
sch_sub_forum_id
FROM
( select * FROM sch_forum_topics WHERE sch_sub_forum_id = 4
ORDER BY topic_last_post_time DESC
LIMIT 0, 15 ) main
INNER JOIN _users
ON ( _users.userid = main.topic_poster )
INNER JOIN _profile
ON _profile.userid = _users.userid
INNER JOIN _class
ON _users.classid = _class.classid
INNER JOIN _level
ON _class.level_id = _level.id
INNER JOIN _unit
ON _class.unitid = _unit.unitid
INNER JOIN _department
ON _unit.deptid = _department.deptid
INNER JOIN _faculty
ON _department.facid = _faculty.facid
INNER JOIN _university
ON _faculty.schid = _university.schid);