MySQL: JOIN multiple tables - mysql

I have the following query I am trying to join 2 tables (' Industry' , 'Country' ) on 2 conditions, but it gives me the following error
Error Code: 1054. Unknown column 'i.id' in 'on clause'
Does anybody know how should I tackle this?
SELECT c.name AS country_name, i.name as industry_name, num_projects, num_consultants, admin_rating
FROM industry i, country c
JOIN (SELECT pc.country_id, pi.industry_id, COUNT(p.id) AS num_projects
FROM project p, project_country pc, project_industry pi
where p.id = pc.project_id and pi.project_id=p.id
GROUP BY pc.country_id,pi.industry_id) x ON x.country_id = c.id and x.industry_id=i.id
JOIN (SELECT u.country_id,ie.industry_id, COUNT(u.id) AS num_consultants
FROM user u, consultant_profile, industry_experience ie
WHERE u.is_active = 1 AND u.type = 0 and
ie.consultant_profile_id= consultant_profile.id
and u.id= consultant_profile.id
GROUP BY u.country_id,ie.industry_id) y ON y.country_id = c.id and y.industry_id = i.id order by num_projects DESC limit 20;
EDIT the table structure is as following:
industry - id
project_industry - industry_id, project_id
industry_experience - consultant_profile_id, industry_id
consultant_profile - id,user_id

Since you still did not provide any sql fiddle
you can start from my one:
http://sqlfiddle.com/#!9/6c0569/1
SELECT pc.country_id, pi.industry_id,
COUNT(p.id) AS num_projects,
COUNT(u.id) AS num_consultants
FROM project p
INNER JOIN project_country pc
ON p.id = pc.project_id
INNER JOIN project_industry pi
ON pi.project_id=p.id
INNER JOIN `user` u
ON u.is_active = 1 AND u.type = 0
and u.country_id = pc.country_id
INNER JOIN industry_experience ie
ON u.id = ie.consultant_profile_id
AND ie.industry_id = pi.industry_id
GROUP BY pc.country_id, pi.industry_id
if you will add some data into that fiddle we can discuss deeper

Related

Ho to get last item in mysql using max()

I want to get the last item as result using max(), but i'm just getting the first item even if im using max()
Here's the SQL code:
SELECT r.correct, r.items, r.percentage,MAX(r.date_taken) as date_taken,
u.username,u.FN, u.user_course_type,
IFNULL(u.user_major_type,'N/A') as user_major_type,u.level_name,
u.section_name
FROM bcc_fs_exam_result r
INNER JOIN
(SELECT u.id_user, u.username, CONCAT(u.lastname,', ',u.firstname) as FN,
c.user_course_type, m.user_major_type, l.level_name, s.section_name
FROM bcc_fs_user u
LEFT JOIN bcc_fs_user_course c on c.id_user_course = u.id_user_course
LEFT JOIN bcc_fs_user_major m on m.id_user_major = u.id_user_major
LEFT JOIN bcc_fs_group_level l ON l.id_level = u.id_level
LEFT JOIN bcc_fs_group_section s ON s.id_section = u.id_section
) u ON r.id_user = u.id_user WHERE r.id_exam = 5 GROUP BY r.id_user
TIA
What I take from your question is that you want to get the "correct", "items", "percentage" ect. columns of the row in bcc_fs_exam_result which has the last or first date.
If that's correct then you can filter bcc_fs_exam_result by first finding what is the min or max date by for each id_user then join that back on the exam results table.
SELECT
r.correct,
r.items,
r.percentage,
r.date_taken,
u.username,
u.FN,
u.user_course_type,
IFNULL(u.user_major_type,'N/A') as user_major_type,
u.level_name,
u.section_name
FROM bcc_fs_exam_result r
INNER JOIN (
SELECT u.id_user,
u.username,
CONCAT(u.lastname,', ',u.firstname) as FN,
c.user_course_type,
m.user_major_type,
l.level_name,
s.section_name
FROM bcc_fs_user u
LEFT JOIN bcc_fs_user_course c on c.id_user_course = u.id_user_course
LEFT JOIN bcc_fs_user_major m on m.id_user_major = u.id_user_major
LEFT JOIN bcc_fs_group_level l ON l.id_level = u.id_level
LEFT JOIN bcc_fs_group_section s ON s.id_section = u.id_section
) u ON r.id_user = u.id_user
INNER JOIN (
SELECT
id_user, max(r.date_taken) as last_date_taken
FROM bcc_fs_exam_result
GROUP BY id_user
) as lastdate ON lastDate.id_user = r.id_user and r.date_taken = lastdate.last_date_taken
which could be more simply written as :
SELECT
r.correct,
r.items,
r.percentage,
r.date_taken,
u.username,
CONCAT(u.lastname,', ',u.firstname) as FN,
c.user_course_type,
IFNULL(m.user_major_type,'N/A') as user_major_type,
l.level_name,
s.section_name
FROM bcc_fs_exam_result r
INNER JOIN (
SELECT
id_user, max(r.date_taken) as last_date_taken
FROM bcc_fs_exam_result
GROUP BY id_user
) as lastdate ON lastDate.id_user = r.id_user and r.date_taken = lastdate.last_date_taken
INNER JOIN bcc_fs_user u on r.id_user = u.id_user
LEFT JOIN bcc_fs_user_course c on c.id_user_course = u.id_user_course
LEFT JOIN bcc_fs_user_major m on m.id_user_major = u.id_user_major
LEFT JOIN bcc_fs_group_level l ON l.id_level = u.id_level
LEFT JOIN bcc_fs_group_section s ON s.id_section = u.id_section
You have assumed that id_user + date_taken is a surrogate key of bcc_fs_exam_result which you should probably enforce with a constraint if at all possible. Otherwise it looks from your sample data that the order of the unique id column id_result follows the date_takenso you might be better to use Max(id_result) rather than Max(date_taken). That would avoid returning duplicate rows for one id_user where two rows of bcc_fs_exam_result have the same taken_date and `id_user.

Combine query that relies on resultset of another

I run this query to get 20 random items from my wordpress database based on things like rating, category, etc
SELECT (A.user_votes/A.user_voters) as site_rating, B.ID as post_id, B.post_author, B.post_date,E.name as category
FROM `wp_gdsr_data_article` as A
INNER JOIN `wp_posts` as B ON (A.post_id = B.id)
INNER JOIN wp_term_relationships C ON (B.ID = C.object_id)
INNER JOIN wp_term_taxonomy D ON (C.term_taxonomy_id = D.term_taxonomy_id)
INNER JOIN wp_terms E ON (D.term_id = E.term_id)
WHERE
B.post_type = 'post' AND
B.post_status = 'publish' AND
D.taxonomy='category' AND
E.name NOT IN ('Satire', 'Declined', 'Outfits','Unorganized', 'AP')
ORDER BY RAND()
LIMIT 20
Then, for each result of the random items, I want to find a corresponding item that is very similar to the random item (around the same rating) but not identical and also one the user has not seen:
SELECT ABS($site_rating-(A.user_votes/A.user_voters)) as diff, (A.user_votes/A.user_voters) as site_rating, B.ID as post_id, B.post_author, B.post_date,E.name as category ,IFNULL(F.count,0) as count
FROM `wp_gdsr_data_article` as A
INNER JOIN `wp_posts` as B ON (A.post_id = B.id)
INNER JOIN wp_term_relationships C ON (B.ID = C.object_id)
INNER JOIN wp_term_taxonomy D ON (C.term_taxonomy_id = D.term_taxonomy_id)
INNER JOIN wp_terms E ON (D.term_id = E.term_id)
LEFT JOIN (
SELECT *,COUNT(*) as count FROM `verus` WHERE ip = '{$_SERVER['REMOTE_ADDR']}'
) as F ON (A.post_id = F.post_id_winner OR A.post_id = F.post_id_loser)
WHERE
E.name = '$category' AND
B.ID <> '$post_id' AND
B.post_type = 'post' AND
B.post_status = 'publish' AND
D.taxonomy='category' AND
E.name NOT IN ('Satire', 'Declined', 'Outfits','Unorganized', 'AP')
ORDER BY count ASC, diff ASC
LIMIT 1
Where the following php variables refer to the result of the previous query
$post_id = $result['post_id'];
$category = $result['category'];
$site_rating = $result['site_rating'];
and $_SERVER['REMOTE_ADDR'] refers to the user's IP.
Is there a way to combine the first query with the 20 additional queries that need to be called to find corresponding items, so that I need just 1 or 2 queries?
Edit: Here is the view that simplifies the joins
CREATE VIEW `versus_random` AS
SELECT (A.user_votes/A.user_voters) as site_rating, B.ID as post_id, B.post_author, B.post_date,E.name as category
FROM `wp_gdsr_data_article` as A
INNER JOIN `wp_posts` as B ON (A.post_id = B.id)
INNER JOIN wp_term_relationships C ON (B.ID = C.object_id)
INNER JOIN wp_term_taxonomy D ON (C.term_taxonomy_id = D.term_taxonomy_id)
INNER JOIN wp_terms E ON (D.term_id = E.term_id)
WHERE
B.post_type = 'post' AND
B.post_status = 'publish' AND
D.taxonomy='category' AND
E.name NOT IN ('Satire', 'Declined', 'Outfits','Unorganized', 'AP')
My attempt now with the view:
SELECT post_id,
(
SELECT INNER_TABLE.post_id
FROM `versus_random` as INNER_TABLE
WHERE
INNER_TABLE.post_id <> OUTER_TABLE.post_id
ORDER BY (SELECT COUNT(*) FROM `versus` WHERE ip = '54' AND (INNER_TABLE.post_id = post_id_winner OR INNER_TABLE.post_id = post_id_loser)) ASC
LIMIT 1
) as innerquery
FROM `versus_random` as OUTER_TABLE
ORDER BY RAND()
LIMIT 20
However the query just timesout and freezes my mysql.
I think it should work like this, but I don't have any Wordpress at hand to test it. The second query that gets the related post is embedded in the other query, when it gets just the related_post_id. The whole query is turned into a subquery itself, given the alias 'X' (although you are free to use 'G', if you want to continue your alphabet.)
In the outer query, the tables for posts and data-article are joined again (RA and RP) to query the relevant fields of the related post, based on the related_post_id from the inner query. These two tables are left joined (and in reverse order), so you still get the main post if no related post was found.
SELECT
X.site_rating,
X.post_id,
X.post_author,
X.post_date,
X.category,
RA.user_votes / RA.user_voters as related_post_site_rating,
RP.ID as related_post_id,
RP.post_author as related_post_author,
RP.post_date as related_post_date,
RP.name as related_category,
FROM
( SELECT
(A.user_votes/A.user_voters) as site_rating,
B.ID as post_id, B.post_author, B.post_date,E.name as category,
( SELECT
RB.ID as post_id
FROM `wp_gdsr_data_article` as RA
INNER JOIN `wp_posts` as RB ON (RA.post_id = RB.id)
INNER JOIN wp_term_relationships RC ON (RB.ID = RC.object_id)
INNER JOIN wp_term_taxonomy RD ON (RC.term_taxonomy_id = RD.term_taxonomy_id)
INNER JOIN wp_terms RE ON (RD.term_id = RE.term_id)
LEFT JOIN (
SELECT *,COUNT(*) as count FROM `verus` WHERE ip = '{$_SERVER['REMOTE_ADDR']}'
) as RF ON (RA.post_id = RF.post_id_winner OR RA.post_id = RF.post_id_loser)
WHERE
RE.name = E.name AND
RB.ID <> B.ID AND
RB.post_type = 'post' AND
RB.post_status = 'publish' AND
RD.taxonomy='category' AND
RE.name NOT IN ('Satire', 'Declined', 'Outfits','Unorganized', 'AP')
ORDER BY count ASC, diff ASC
LIMIT 1) as related_post_id
FROM `wp_gdsr_data_article` as A
INNER JOIN `wp_posts` as B ON (A.post_id = B.id)
INNER JOIN wp_term_relationships C ON (B.ID = C.object_id)
INNER JOIN wp_term_taxonomy D ON (C.term_taxonomy_id = D.term_taxonomy_id)
INNER JOIN wp_terms E ON (D.term_id = E.term_id)
WHERE
B.post_type = 'post' AND
B.post_status = 'publish' AND
D.taxonomy='category' AND
E.name NOT IN ('Satire', 'Declined', 'Outfits','Unorganized', 'AP')
ORDER BY RAND()
LIMIT 20
) X
LEFT JOIN `wp_posts` as RP ON RP.id = X.related_post_id
LEFT JOIN `wp_gdsr_data_article` as RA.post_id = RP.id
I can't test my proposal so take it with the benefit of the doubt. Anyway i hope it could be a valid starting point for some of the issues faced.
I can not imagine a solution that does not pass through a temporary table, cabling onerous computations present in your queries. You could also have the goal to not interfere with the randomization of the first phase. In the following I try to clarify.
I'll start with these rewritings:
-- first query
SELECT site_rating, post_id, post_author, post_date, category
FROM POSTS_COMMON
ORDER BY RAND()
LIMIT 20
-- second query
SELECT ABS(R.site_rating_A - R.site_rating_B) as diff, R.site_rating_B as site_rating, P.post_id, P.post_author, P.post_date, P.category, F.count
FROM POSTS_COMMON AS P
INNER JOIN POSTS_RATING_DIFFS AS R ON (P.post_id = R.post_id_B)
LEFT JOIN (
/* post_id_winner, post_id_loser explicited; COUNT(*) NULL treatment anticipated */
SELECT post_id_winner, post_id_loser, IFNULL(COUNT(*), 0) as count FROM `verus` WHERE ip = '{$_SERVER['REMOTE_ADDR']}'
) as F ON (P.post_id = F.post_id_winner OR P.post_id = F.post_id_loser)
WHERE
P.category = '$category'
AND R.post_id_A = '$post_id'
ORDER BY count ASC, diff ASC
LIMIT 1
with:
SELECT A.post_id_A, B.post_id_B, A.site_rating as site_rating_A, B.site_rating as site_rating_B
INTO POSTS_RATING_DIFFS
FROM POSTS_COMMON as A, POSTS_COMMON as B
WHERE A.post_id <> B.post_id AND A.category = B.category
CREATE VIEW POSTS_COMMON AS
SELECT A.ID as post_id, A.user_votes, A.user_voters, (A.user_votes / A.user_voters) as site_rating, B.post_author, B.post_date, E.name as category
FROM wp_gdsr_data_article` as A
INNER JOIN `wp_posts` as B ON (A.post_id = B.post_id)
INNER JOIN wp_term_relationships C ON (B.ID = C.object_id)
INNER JOIN wp_term_taxonomy D ON (C.term_taxonomy_id = D.term_taxonomy_id)
INNER JOIN wp_terms E ON (D.term_id = E.term_id)
WHERE
B.post_type = 'post' AND
B.post_status = 'publish' AND
D.taxonomy='category' AND
E.name NOT IN ('Satire', 'Declined', 'Outfits','Unorganized', 'AP')
POSTS_COMMON isolates a common view between the two queries.
With POSTS_RATING_DIFFS, a temporary table populated with the ratings combinations and diffs, we have "the trick" of transforming the inequality join criteria on post_id(s) in an equality one (see R.post_id_A = '$post_id' in the second query).
We also take advantage of a temporary table in having precomputed ratings for the combinatory explosion of A.post_id <> B.post_id (with post category equality), and moreover being useful for other sessions.
Also extracting the RAND() ordering in a temporary table could be advantageous. In this case we could limit the ratings combinations and diffs only on the 20 randomly chosen.
Original limiting to one single row in the dependent second level query is done by mean of ordering and limit statements.
The proposed solution avoids elaborating a LIMIT 1 on an ORDER BY resultset in the second level query wich become a subquery.
The single row calculation in the subquery is done by mean of a WHERE criteria on the maximum of a single value calculated from the columns values on which ORDER BY clause is used.
The combination into a single value must be valid in preserving the correct ordering. I'll leave in pseudo-code as:
'<combination of count and diff>'
For example, using combination of the two values into a string type, we could have:
CONCAT(LPAD(CAST(count AS CHAR), 10, '0'), LPAD(CAST(ABS(diff) AS CHAR), 20, '0'))
The structure of the single query would be:
SELECT (Q_LVL_1.user_votes/Q_LVL_1.user_voters) as site_rating_LVL_1, Q_LVL_1.post_id as post_id_LVL_1
, Q_LVL_1.post_author as post_author_LVL_1, Q_LVL_1.post_date as post_date_LVL_1
, Q_LVL_1.category as category_LVL_1, Q_LVL_2.post_id as post_id_LVL_2
, Q_LVL_2.diff as diff_LVL_2, Q_LVL_2.site_rating as site_rating_LVL_2
, Q_LVL_2.post_author as post_author_LVL_2, Q_LVL_2.post_date as post_date_LVL_2
, Q_LVL_2.count
FROM POSTS_COMMON AS Q_LVL_1
, /* 1-row-selection query placed side by side for each Q_LVL_1's row */
(
SELECT CORE_P.post_id, CORE_P.ABS_diff as diff, P.site_rating, P.post_author, P.post_date, CORE_P.count
FROM POSTS_COMMON AS P
INNER JOIN (
SELECT FIRST(CORE_P.post_id) as post_id, ABS(CORE_P.diff) as ABS_diff, CORE_P.count
FROM (
/*
selection of posts with post_id(s) different from first level query,
not already taken and with the topmost value of
'<combination of count and diff>'
*/
) AS CORE_P
GROUP BY CORE_P.count, ABS(CORE_P.diff)
/* the one row selector */
) AS CORE_ONE_LINER ON P.post_id = CORE_ONE_LINER.post_id
) AS Q_LVL_2
ORDER BY RAND()
LIMIT 20
CORE_P selection could have more post_id(s) corresponding to the topmost value '<combination of count and diff>', so the use of GROUP BY and FIRST clauses to reach the single row.
This brings to a possible final implementation:
SELECT (Q_LVL_1.user_votes/Q_LVL_1.user_voters) as site_rating_LVL_1, Q_LVL_1.post_id as post_id_LVL_1
, Q_LVL_1.post_author as post_author_LVL_1, Q_LVL_1.post_date as post_date_LVL_1
, Q_LVL_1.category as category_LVL_1, Q_LVL_2.post_id as post_id_LVL_2
, Q_LVL_2.diff as diff_LVL_2, Q_LVL_2.site_rating as site_rating_LVL_2
, Q_LVL_2.post_author as post_author_LVL_2, Q_LVL_2.post_date as post_date_LVL_2
, Q_LVL_2.count
FROM POSTS_COMMON AS Q_LVL_1
, (
SELECT CORE_P.post_id, CORE_P.ABS_diff as diff, P.site_rating, P.post_author, P.post_date, CORE_P.count
FROM POSTS_COMMON AS P
INNER JOIN
(
SELECT FIRST(CORE_P.post_id) as post_id, ABS(CORE_P.diff) as ABS_diff, CORE_F.count
FROM (
SELECT CORE_RATING.post_id as post_id, ABS(CORE_RATING.diff) as ABS_diff, CORE_F.count
FROM (
SELECT post_id_B as post_id, site_rating_A - site_rating_B as diff
FROM POSTS_RATING_DIFFS
WHERE POSTS_RATING_DIFFS.post_id_A = Q_LVL_1.post_id
) as CORE_RATING
LEFT JOIN (
SELECT post_id_winner, post_id_loser, IFNULL(COUNT(*), 0) as count
FROM `verus`
WHERE ip = '{$_SERVER['REMOTE_ADDR']}'
) as CORE_F ON (CORE_RATING.post_id = CORE_F.post_id_winner OR CORE_RATING.post_id = CORE_F.post_id_loser)
WHERE
POSTS_RATING_DIFFS.post_id_A = Q_LVL_1.post_id
AND '<combination of CORE_F.count and CORE_RATING.diff>'
= MAX (
SELECT '<combination of CORE_F_2.count and CORE_RATING_2.diff>'
FROM (
SELECT site_rating_A - site_rating_B as diff
FROM POSTS_RATING_DIFFS
WHERE POSTS_RATING_DIFFS.post_id_A = Q_LVL_1.post_id
) as CORE_RATING_2
LEFT JOIN (
SELECT post_id_winner, post_id_loser, IFNULL(COUNT(*), 0) as count
FROM `verus`
WHERE ip = '{$_SERVER['REMOTE_ADDR']}'
) as CORE_F_2 ON (CORE_RATING_2.post_id = CORE_F_2.post_id_winner OR CORE_RATING_2.post_id = CORE_F_2.post_id_loser)
) /* END MAX */
) AS CORE_P
GROUP BY CORE_P.count, ABS(CORE_P.diff)
) AS CORE_ONE_LINER ON P.post_id = CORE_ONE_LINER.post_id
) AS Q_LVL_2
ORDER BY RAND()
LIMIT 20

mySQL - use outer SELECT value in subselect in SELECT clause

I have this query:
SELECT c.id, p.id, p.register_date, o.office_agency_name_1, a.street_address, a.supplemental_address_1, a.city, s.abbreviation, co.iso_code, a.postal_code, ph.phone, pf.phone, e.email,
ab.name, c.addressee_custom, (Select phone from civicrm_phone where contact_id = civicrm_contact.id AND is_billing = 1) as billing_phone
FROM civicrm_contact c,
civicrm_participant p,
civicrm_value_office_info_1 o,
civicrm_address a,
civicrm_state_province s,
civicrm_country co,
civicrm_phone ph,
civicrm_phone pf,
civicrm_email e,
civicrm_address ab
WHERE p.contact_id = c.id
AND p.is_test = 0
AND p.event_id = 1
AND p.status_id NOT IN (4,11,12)
AND ( c.is_deleted = 0 OR c.is_deleted IS NULL )
AND o.entity_id = c.id
AND a.contact_id = c.id
AND s.id = a.state_province_id
AND co.id = a.country_id
AND ph.contact_id = c.id
AND ph.is_primary = 1
AND pf.contact_id = c.id
AND pf.phone_type_id = 3
AND e.contact_id = c.id
AND e.is_primary = 1
AND ab.contact_id = c.id
AND ab.is_billing = 1
billing_phone is the most recent addition ... this is of course not working and giving me:
1054 - Unknown column 'civicrm_contact.id' in 'where clause'
Due to the complexity, and the fact that there are more fields yet to add, I'd like to avoid JOINs if possible, and stay as close to the current syntax as possible.
When I tried to add billing phone with the same pattern as the others, it became apparent that not everyone has a billing phone - the number of rows dropped dramatically.
I'd like to make this work as a subquery in the outer SELECT (which would get me NULLs for those rows with no billing phone, right?).
Actually, it doesn't work as a JOIN either:
SELECT c.id, p.id, p.register_date, o.office_agency_name_1, a.street_address, a.supplemental_address_1, a.city, s.abbreviation, co.iso_code, a.postal_code, ph.phone, pf.phone, e.email,
ab.name, c.addressee_custom, pb.phone as billing_phone
FROM civicrm_contact c,
civicrm_participant p,
civicrm_value_office_info_1 o,
civicrm_address a,
civicrm_state_province s,
civicrm_country co,
civicrm_phone ph,
civicrm_phone pf,
civicrm_email e,
civicrm_address ab
LEFT JOIN civicrm_phone as pb on pb.contact_id = c.id AND pb.is_billing = 1
WHERE p.contact_id = c.id
AND p.is_test = 0
AND p.event_id = 1
AND p.status_id NOT IN (4,11,12)
AND ( c.is_deleted = 0 OR c.is_deleted IS NULL )
AND o.entity_id = c.id
AND a.contact_id = c.id
AND s.id = a.state_province_id
AND co.id = a.country_id
AND ph.contact_id = c.id
AND ph.is_primary = 1
AND pf.contact_id = c.id
AND pf.phone_type_id = 3
AND e.contact_id = c.id
AND e.is_primary = 1
AND ab.contact_id = c.id
AND ab.is_billing = 1
That gives me:
1054 - Unknown column 'c.id' in 'on clause'
How do I make this work?
What it appears is that the aliased table "c" (which refers to civicrm_contact) doesn't have a column "id" in it.
Are you sure this column exists in the table?

SQL - Issue with Having and Grouping

Hi I'm having an issue with a query that was once working. My SQL skills aren't all that great, not sure what I'm missing. Or if this is the correct approach. Maybe use a temp table instead?
The basic gist is given a certain time frame, I need to calculate the highest aggregate of points over 5 classes.
trialScores - keeps scores/points,
trials, dog, people and member tables are just meta data
classId 5 requires a different date range
Here is my Query on MySQL
select
t.id,
d.id,
p.id,
p.firstname,
p.lastname,
d.id dogId,
d.dogName,
c.id,
c.class,
t.trialStartDate,
s.points,
if(c.id = 5, '2012-08-01', '2012-11-18') as startDate,
if(c.id = 5, '2013-07-31', '2013-12-31') as endDate,
SUM(ts.points) AS pointsAggregate
from trialScores ts
inner join trials t on t.id = ts.trialId
inner join dogs d on d.id = ts.dogId
inner join people p on p.id = ts.personId
inner join classes c on c.id = ts.classId
where t.deletedAt is null
and ts.deletedAt is null
and ts.memberAtTrial = 1
and d.omitFromTripleCrownDOY = 0
and t.associationId = 1
GROUP BY p.id, ts.dogId, ts.classId
having t.trialStartDate between startDate and endDate
order by ts.classId, pointsAggregate desc
Looks like this fixed it, too much in the select and not in Group by?:
select
d.dogName,
c.class,
p.firstName,
p.lastName,
SUM(ts.points) AS pointsAggregate
from trialScores ts
inner join trials t on t.id = ts.trialId
inner join dogs d on d.id = ts.dogId
inner join people p on p.id = ts.personId
inner join classes c on c.id = ts.classId
where t.deletedAt is null
and ts.deletedAt is null
and ts.memberAtTrial = 1
and d.omitFromTripleCrownDOY = 0
and t.associationId = 1
and t.trialStartDate between if(c.id = 5, '2012-08-01', '2012-11-18') and if(c.id = 5, '2013-07-31', '2013-12-31')
GROUP BY ts.dogId, ts.classId
order by ts.classId, pointsAggregate desc
Can you try below query and let if it's work or not ?
select
d.dogName,
c.class,
p.firstName,
p.lastName,
SUM(ts.points) AS pointsAggregate
from trialScores ts
inner join trials t on t.id = ts.trialId
inner join dogs d on d.id = ts.dogId
inner join people p on p.id = ts.personId
inner join classes c on c.id = ts.classId
where t.deletedAt is null
and ts.deletedAt is null
and ts.memberAtTrial = 1
and d.omitFromTripleCrownDOY = 0
and t.associationId = 1
and t.trialStartDate between if(c.id = 5, '2012-08-01', '2012-11-18') and if(c.id = 5, '2013-07-31', '2013-12-31')
GROUP BY ts.classId,p.firstName,p.lastName
order by ts.classId, pointsAggregate desc

MySql query: sometimes getting an empty result set

I have this query:
SELECT CONCAT(f.name, ' ', f.parent_names) AS FullName,
stts.name AS 'Status',
u.name AS Unit,
city.name AS City,
hus.mobile1 AS HusbandPhone,
wife.mobile1 AS WifePhone,
f.phone AS HomePhone,
f.contact_initiation_date AS InitDate,
fh.created_at AS StatusChangeDate,
cmt.created_at AS CommentDate,
cmt.comment AS LastComment,
f.reconnection_date AS ReconnectionDate,
(
SELECT GROUP_CONCAT(t.name)
FROM taggings tgs JOIN tags t
ON tgs.tag_id = t.id
WHERE tgs.taggable_type = 'family' AND
tgs.taggable_id = f.id
) AS HandlingStatus
FROM families f
JOIN categories stts ON f.family_status_cat_id = stts.id
JOIN units u ON f.unit_id = u.id
JOIN categories city ON f.main_city_cat_id = city.id
JOIN contacts hus ON f.husband_id = hus.id
JOIN contacts wife ON f.wife_id = wife.id
JOIN comments cmt ON f.id = cmt.commentable_id AND
cmt.created_at = (SELECT MAX(created_at) FROM comments WHERE commentable_id = f.id)
JOIN family_histories fh ON f.id = fh.family_id AND
fh.created_at = (SELECT MAX(created_at) FROM family_histories WHERE family_id = f.id AND family_history_cat_id = 1422) AND
fh.family_history_cat_id = 1422
WHERE f.id = 12212
The problem is with the second SELECT (the column - HandlingStatus).
I don't understand but when the column has results (tested as a stand alone query) - I get an empty result set, and when there are no results - I get a result.
Why?