Search code examples
sqlpostgresqlcross-join

No zero values in COUNT with 2 ORDER BY statments


I have 3 tables:

+---------+    +----------+    +----------+
|  kkw    |    |  block   |    |  status  |
+---------+    +----------+    +----------+
| kkw_id  |    | block_id |    |status_id |
| land_id |    | kkw_id   |    | ....     |
| ...     |    | status_id|    | ....     |
+---------+    +----------+    +----------+

And I want to display the number of blocks per country (land_id) and status, with zero if a country has no block corresponding to a status. I try this request, but no zero values are displayed:

SELECT s.status_id, k.land_id, COUNT(b.block_id)
FROM kkw_status AS s
LEFT JOIN block AS b ON s.status_id = b.status_id
LEFT JOIN kkw AS k ON b.kkw_id=k.kkw_id
GROUP BY s.status_id, k.land_id
ORDER BY k.land_id, s.status_id;

Result:

status_id   land_id count
    1          1      2
    4          1      3  ....

But I would like:

status_id   land_id count
    1          1      2
    2          1      0
    3          1      0
    4          1      3  .....

Any idea ? Thanks


Solution

  • You are grouping by k.land_id. Hence, when something doesn't match, it gets a value of NULL for this column. So, zero values would only show up on such rows.

    If you want all status_ids and land_ids, then create a list of all of them using cross join and then calculate the number that match each group. I think this is what the query looks like:

    SELECT s.status_id, k.land_id, COUNT(b.block_id)
    FROM kkw_status s CROSS JOIN
         kkw k LEFT JOIN
         block b
         ON b.status_id = s.status_id AND b.kkw_id = k.kkw_id
    GROUP BY s.status_id, k.land_id
    ORDER BY k.land_id, s.status_id;