-- Using A PostgreSQL crosstab() Function With More Than Three Columns SELECT employee AS "Salesman", title AS "Title", emp_total AS "Total", COALESCE(Jan, 0) AS "Jan", COALESCE(Feb, 0) AS "Feb", mar AS "Mar", COALESCE(Apr, 0) AS "Apr" FROM crosstab( $$ SELECT e.last_name || ' ' || e.first_name as salesman, e.title , et.emp_total , date_part('Mon',order_date) AS order_month, SUM(ROUND((quantity * unit_price)::numeric, 2)) AS order_total FROM employees e JOIN ( SELECT e.employee_id , SUM(ROUND((quantity * unit_price)::numeric, 2)) AS emp_total FROM employees e JOIN orders o ON e.employee_id = o.employee_id JOIN order_details od ON o.order_id = od.order_id WHERE date_part('year', order_date) = 1997 AND date_part('month', order_date) BETWEEN 1 AND 4 GROUP BY 1 ) et on e.employee_id = et.employee_id JOIN orders o ON e.employee_id = o.employee_id JOIN order_details od ON o.order_id = od.order_id WHERE date_part('year', order_date) = 1997 AND date_part('month', order_date) BETWEEN 1 AND 4 GROUP BY 1,2,3,4 UNION ALL SELECT '' AS salesman, 'Month Total' AS title, ( SELECT SUM(ROUND((quantity * unit_price)::numeric, 2)) AS order_total FROM orders o JOIN order_details od ON o.order_id = od.order_id WHERE date_part('year', order_date) = 1997 AND date_part('month', order_date) BETWEEN 1 AND 4 ) AS col_total, date_part('Mon',order_date) AS order_month, SUM(ROUND((quantity * unit_price)::numeric, 2)) AS order_total FROM employees e JOIN orders o ON e.employee_id = o.employee_id JOIN order_details od ON o.order_id = od.order_id WHERE date_part('year', order_date) = 1997 AND date_part('month', order_date) BETWEEN 1 AND 4 GROUP BY 1,2,3, 4 $$, $$ SELECT DISTINCT date_part('month', order_date) AS order_month FROM orders WHERE date_part('year', order_date) = 1997 AND date_part('month', order_date) BETWEEN 1 AND 4 ORDER BY 1 $$ ) AS ct (employee text, title text, emp_total numeric, Jan numeric, Feb numeric, Mar numeric, Apr numeric);