what I am trying to do is performing a query that has multiple results of the same query by just editing only a where clause.
The goal is to query a result of the same dataset in different date ranges, but instead of performing multiple separated queries, having one single query that queries the tables X times (depending on the selected date ranges).
For example:
SELECT database_one.users.firstname,
database_one.users.lastname,
COUNT(*) AS "Total"
FROM database_two.announcements
INNER JOIN database_one.prospect_evaluations ON database_one.prospect_evaluations.announcement_id = database_two.announcements.id
INNER JOIN database_one.users ON database_one.prospect_evaluations.user_id = database_one.users.id
WHERE (database_two.announcements.deleted_at IS NULL
AND (database_two.announcements.archived_at IS NOT NULL
AND database_two.announcements.crmstate != 'Scartata'))
AND (database_two.announcements.archived_at > DATE_SUB(NOW(), INTERVAL 1 MONTH)) /* THIS IS THE DATE RANGE TO EDIT IN THE SUBQUERY */
GROUP BY database_one.prospect_evaluations.user_id
ORDER BY database_two.announcements.id DESC
What I'd like to have is something like this, in pseudo-sql:
SELECT database_one.users.firstname,
database_one.users.lastname,
COUNT(*) AS "Total",
/* PSEUDO-SQL START { */
COUNT(*) WHERE (database_two.announcements.archived_at > DATE_SUB(NOW(), INTERVAL 1 MONTH)) AS "1 Month"
COUNT(*) WHERE (database_two.announcements.archived_at > DATE_SUB(NOW(), INTERVAL 3 MONTH)) AS "3 Months"
COUNT(*) WHERE (database_two.announcements.archived_at > DATE_SUB(NOW(), INTERVAL 6 MONTH)) AS "6 Months"
COUNT(*) WHERE (database_two.announcements.archived_at > DATE_SUB(NOW(), INTERVAL 1 YEAR)) AS "1 Year"
/* } PSEUDO-SQL STOP */
FROM database_two.announcements
INNER JOIN database_one.prospect_evaluations ON database_one.prospect_evaluations.announcement_id = database_two.announcements.id
INNER JOIN database_one.users ON database_one.prospect_evaluations.user_id = database_one.users.id
WHERE (database_two.announcements.deleted_at IS NULL
AND (database_two.announcements.archived_at IS NOT NULL
AND database_two.announcements.crmstate != 'Scartata'))
GROUP BY database_one.prospect_evaluations.user_id
ORDER BY database_two.announcements.id DESC
Best Answer
Your pseudo-SQL is surprising close to the standard SQL clause
FILTER
, which has only been implemented by Postgres but unfortunately not by MySQL:The good news is that in MySQL you can use equivalent (and standard SQL as well)
CASE
expressions:or the more compact but non-standard
SUM()
that uses the implicit conversions of boolean values (TRUE and FALSE) to 1 and 0:By the way, you could use aliases for the various tables in the
FROM
clauses so the query becomes shorter and usually more readable.Also the
announcements.id
is ambiguous in theSELECT
orrORDER BY
clause after aGROUP BY
, because it is not in the group by list. UseMIN()
orMAX()
or some otherORDER BY
instead.The query with aliases - and assuming you choose the
SUM()
solution from above: