Question: ```
T1 - id, name, userID (stocks) - not really used in this cased
T2 - id, name, stockID, userID (categories)
T3 - id, name, stockID, categoryID, quality, userID (goods)

```

column "quality" can be "0" (good) or "1" (bad) and each goods (even same sort) = 1 row

this SQL, (this "far" I can get), show only total count of good and bad stuff, and if category exist, but haven't any rows, then it's not shown in final results:

```
SELECT T2.name, COUNT(*) AS TOTAL FROM T3
LEFT JOIN T2 ON T2.id=T3.categoryID
WHERE T3.stockID=2 GROUP BY T3.categoryID

```

Result:

```
CATEGORY  - TOTAL
category1 - 1237
category2 -  857
category3 -  125

```

category4 is not shown, because no rows exist, but I need every single rows been shown, even if T3 rows doesn't exist and BAD stuff count of course..

Desired result:

```
CATEGORY  - BAD / TOTAL
category1 - 425 / 1237
category2 - 326 /  857
category3 -   0 /  125
category4 -   0 /    0

```

Answer: 
```
SELECT T2.name, SUM(CASE WHEN T3.quality=1 THEN 1 ELSE 0 END)AS BAD,
       COUNT(*)AS TOTAL 
FROM T2
LEFT JOIN T3 ON T2.id=T3.categoryID
WHERE t2.stockid=2
GROUP BY T2.name;

```
I think you want to do the `left join` in the other direction (you could also do a `right outer join`). And change the `count()` to count matching records:

```
SELECT T2.name, coalesce(SUM(t.3bad), 0) as Bad, COUNT(t3.categoryID) AS TOTAL
FROM T2 LEFT JOIN
     T3
     ON T2.id = T3.categoryID and T3.stockID = 2;
GROUP BY T2.name;

```

Also, it is a good idea to `select` the same fields that are in the `group by` clause. Really, more than a good idea. Most databases (and the standard) generally require this. The MySQL extension to `group by` can cause problems.

Note that I moved the `where` condition into the `on` clause. This prevents additional filtering that would remove the rows you want.