0

I have a SQL select statement with multiple UNION ALL keywords connecting otherwise independent SQL statements. The query is too complex for me to do without the UNION ALL keywords.

However, I want to limit all of the subqueries to a specific date range and I don't want to write the exact same where clause at the end of each of them. Is there a way I can write one WHERE clause for all of them?

I tried the following code, but it doesn't work because the COUNT(*) phrase prevents the inputDate column from being filtered for every record. Also from a performance standpoint it is probably better to filter by the date column first if there is a way to do that.

SELECT * FROM (
    SELECT count(*), inputDate 'sel1' as name FROM tblName WHERE name IN ('n1','n2')
    UNION ALL
    SELECT count(*), inputDate, 'sel2' as name FROM tblName WHERE name IN ('n3','n4')
    UNION ALL
    SELECT count(*), inputDate, 'sel3' as name FROM tblName WHERE name IN ('n5','n6')
) names WHERE inputDate >= DATE_SUB(NOW(), INTERVAL 1 MONTH)
halfer
  • 19,824
  • 17
  • 99
  • 186
user3413723
  • 11,147
  • 6
  • 55
  • 64
  • Refer this one http://stackoverflow.com/questions/1266666/using-union-and-count-together-in-sql-query – Ataboy Josef Jul 28 '15 at 11:27
  • @AtaboyJosef That one doesn't discuss my key question here - how to use a `WHERE` clause over multiple `UNION ALL` statements. The way to solve the problem may be similar, but the questions are not. – user3413723 Jul 28 '15 at 11:43

1 Answers1

2

You would need to do the count(*) in the outer query:

SELECT name, count(*), inputdate
FROM (SELECT inputDate, 'sel1' as name FROM tblName WHERE name IN ('n1','n2')
      UNION ALL
      SELECT inputDate, 'sel2' as name FROM tblName WHERE name IN ('n3','n4')
      UNION ALL
      SELECT inputDate, 'sel3' as name FROM tblName WHERE name IN ('n5','n6')
     ) names
WHERE inputDate >= DATE_SUB(NOW(), INTERVAL 1 MONTH)
GROUP BY name;

EDIT:

Actually, if these are all from the same table, you don't need the union all:

select (case when name in ('n1', 'n2') then 'sel1'
             when name in ('n3', 'n4') then 'sel2'
             when name in ('n5', 'n6') then 'sel3'
        end) as grp, count(*)
from tblName
where inputDate >= DATE_SUB(NOW(), INTERVAL 1 MONTH) and
      name in ('n1', 'n2', 'n3', 'n4',' n5', 'n6')
group by grp;
Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786