Hola a todos!!
Revisa si te sirve la instrucción PIVOT de MSSQL que lo que hace es agrupar registro en columnas en función del valor de un campo (ejemplo mes) y para estos temas es útil, aunque tiene algunas limitaciones, como solo poder utilizar un único campo de pivot, con una única función de resultado
Aqui te dejo este ejemplo aplicado a tu sentencia, donde obtienes en un único registro la cuenta y el saldo para cada uno de los doce meses
Código SQL
[-]
SELECT tcuenta,
ISNULL([1], 0) as enero,
ISNULL([2], 0) as febrero,
ISNULL([3], 0) as marzo,
ISNULL([4], 0) as abril,
ISNULL([5], 0) as mayo,
ISNULL([6], 0) as junio,
ISNULL([7], 0) as julio,
ISNULL([8], 0) as agosto,
ISNULL([9], 0) as septiembre,
ISNULL([10], 0) as octubre,
ISNULL([11], 0) as noviembre,
ISNULL([12], 0) as diciembre
FROM (
select tcuenta, month(tperiod) as mes, sum(tdebe)-sum(thaber) as saldo
from cdtrans as tr
where year(tperiod) = year(getdate())
and tcuenta is not null
group by tcuenta, month(tperiod)
) AS SourceTable
PIVOT (
sum(saldo) -- aqui es necesario poner siempre una función para obtener resultados
FOR mes IN ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12])
) AS PivotTable
Y aquí integrándolo con el resto de tu sentencia
Código SQL
[-]
select cac.mcuenta, cac.mnombre,
saldo.enero,
-- ...,
saldo.diciembre,
inicial.saldo
from cacuent as cac
left join (
select tr.tcuenta, sum(tdebe) as debe, sum(thaber) as haber, sum(tdebe)-sum(thaber) as saldo
from cdtrans as tr
where year(tperiod) = 2006
and tcuenta is not null
group by tcuenta
) as inicial on cac.MCUENTA = inicial.TCUENTA
left join (
SELECT tcuenta,
ISNULL([1], 0) as enero,
ISNULL([2], 0) as febrero,
ISNULL([3], 0) as marzo,
ISNULL([4], 0) as abril,
ISNULL([5], 0) as mayo,
ISNULL([6], 0) as junio,
ISNULL([7], 0) as julio,
ISNULL([8], 0) as agosto,
ISNULL([9], 0) as septiembre,
ISNULL([10], 0) as octubre,
ISNULL([11], 0) as noviembre,
ISNULL([12], 0) as diciembre
FROM (
select tcuenta, month(tperiod) as mes, sum(tdebe)-sum(thaber) as saldo
from cdtrans as tr
where year(tperiod) = 2006
and tcuenta is not null
group by tcuenta, month(tperiod)
) AS SourceTable
PIVOT (
sum(saldo)
FOR mes IN ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12])
) AS PivotTable
) saldo on cac.MCUENTA = saldo.tcuenta
Para obtener los otros campos (las suma del debe y del haber) tendrías que insertar otros dos bloques mas de JOIN. De esta forma finalmente se te quedarían tan solo 4 bloques JOIN en la consulta (calculo inicial, calculo debe, calculo haber y saldos) frente a los 13 bloques que tienes actualmente.
Un Saludo