I would just do a normal select with a GROUP BY over the month and have your UI handle displaying it as 12 columns across. If you really need to do it though, then this should work:
SELECT
D.name,
AVG(CASE WHEN MONTH(V.visit_date) = 1 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 2 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 3 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 4 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 5 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 6 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 7 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 8 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 9 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 10 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 11 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 12 THEN V.cost ELSE NULL END)
FROM
Doctors D
INNER JOIN Visits V ON
V.id_doc = D.id AND
V.visit_date BETWEEN '2009-01-01' AND '2009-12-31'
GROUP BY
D.name
ORDER BY
D.name
You might need to change the date functions based on your RDBMS. Also, you may need to fiddle with the edge cases - if your dates have a time component it won't catch rows on 12/31.
Finally, I don't know if this changes between RDBMSs and I can't test right now, but if AVG counts a NULL as 0 cost instead of discounting them then you may need to do your own averag - SUM(CASE ... cost ... 0)/SUM(CASE ... 1 ... 0). I hope that makes sense.