Вы должны работать в обратном направлении. Чтобы получить строки для несуществующих дат, необходимо внешнее соединение их со строками, которые имеют эти даты. Для внешнего соединения необходимо иметь последовательность, к которой нужно присоединиться. Поскольку у вас нет последовательности, вам нужно ее создать.
Чтобы создать эту последовательность, у вас есть два варианта:
- Создать статическую последовательность дат и сохранить ее в постоянной таблице (ответ Ларри); или
- Используйте существующую числовую последовательность (например, spt_values), чтобы создать ее на лету.
Предположим, вам нужна гибкость второго подхода. Вот общий фрагмент, который я использую для таких вещей:
SELECT DATEADD(DAY, v.number, @fromdate)
FROM master.dbo.spt_values v
WHERE v.type = 'P'
AND v.number <= DATEDIFF(DAY, @fromdate, @todate)
Теперь просто добавьте это в CTE и присоединитесь к нему:
WITH Dates_CTE (dt) AS
(
-- // Paste the snippet above in here
)
SELECT d.dt AS paymentdate, ISNULL(SUM(p.paymentamount), 0) AS subtotal
FROM Dates_CTE d
LEFT JOIN tblpayment p
ON p.paymentdate = d.dt
GROUP BY d.dt
ORDER BY d.dt
(Обновление: я пропустил предложение WHERE в основном запросе, поскольку он технически обрабатывается соединением, но в некоторых случаях вы можете повысить производительность, оставив его в)
Что касается конвертации валюты, посмотрите синтаксис PIVOT.
Обновление в PIVOT: вы можете просто заключить весь запрос в скобки, а затем:
SELECT paymentdate, [Euro] AS euroamount, [Pound] as poundamount
FROM
(
-- // Insert the full query from above in here
) p
PIVOT
(
SUM(subtotal)
FOR paymentcurrency IN ([Euro], [Pound])
) AS pvt
Трудно проверить, не зная точно, какие данные там находятся, но попробуйте это как отправную точку.