Scenario:
Field names of Table1 named as testtable
id,name,size,width,height
Field names of Table2 named as errortable
id,desc,field1,field2,operator
Values of errortable
+----+-------------------------------------+--------+--------+----------+
| id | desc | field1 | field2 | operator |
+----+-------------------------------------+--------+--------+----------+
| 1 | size should not greater than width | size | width | > |
| 2 | size should not greater than height | size | height | > |
| 3 | with should be equal to height | width | height | <> |
+----+-------------------------------------+--------+--------+----------+
Now I want to check from testtable
:
- count all those records where size > width.
- count all those records where size > height.
- count all those records where width <> height.
Required Output
+-------------------------------------+-------+
| errorname | count |
+-------------------------------------+-------+
| size should not greater than width | 6 |
| size should not greater than height | 2 |
| with should be equal to height | 3 |
+-------------------------------------+-------+
Is it possible to do like this?
Current query:
select desc,
(select count(*) as "Total Errors"
from testtable
where errortable.field1 errortable.operator errortable.field2 )
from errortable group by id;
Best Answer
Assumptions and Clarification
is a reserved word in SQL, don't use it as identifier. Usingdesc
descr
instead.1. Basic query
The fastest and most elegant way to get multiple partial counts from the same table is a single
SELECT
statement with multiple aggregate functions using theFILTER
clause:A statement like:
Or, for Postgres 9.3:
2. Advanced query
To get the result in the form you want it, I counter-pivot with a
VALUES
expression in aLATERAL
join, adding the ID and descriptionid, descr
in the process:Bold parts come from the
errortable
when building the statement dynamically:3. Dynamic query
To concatenate the above statement dynamically from values provided in
errortable
:format()
with%I
quotes column names where necessary and makes the statement safe against SQL injection - except foroperator
, which is concatenated as is. You might be able to make that safe, too, with theOPERATOR()
construct ...If untrusted users don't have write access to
errortable
, you can control its content and need not worry.4. Full automation
Since the return type is uniform and well known, we can encapsulate it in a function:
Call:
Simplifying the concatenation by one more step with an outer
format()
. Also note how all columns are table-qualified to avoid conflicts.Again, since dynamic SQL is involved, make sure it cannot be abused for SQL injection.
SQL Fiddle for Postgres 9.3 since 9.4 is not available.