I have a query that looks like this:
SELECT OrganizationName, OrganizationID, ReceivableStatus, InvoiceFee
FROM v_InvoicesFreelanceOutstanding
ORDER BY Organizat
This looks like a job for pivot if you're using SQL Server 2005 or later.
EDIT:
Since you already know about pivot
, you know it does almost what you need.
You already have the following query:
SELECT
MAX(OrganizationName) as OrganizationName,
OrganizationID,
ReceivableStatus,
SUM(InvoiceFee) as TotalDue
FROM v_InvoicesFreelanceOutstanding
GROUP BY OrganizationID, ReceivableStatus
Which gives you the current, 30-60, 60-90 and 90+ parts that you need. If you pivot that, you get everything you need except for your total. So just throw in the total:
(SELECT
MAX(OrganizationName) as OrganizationName,
OrganizationID,
ReceivableStatus,
SUM(InvoiceFee) as TotalDue
FROM v_InvoicesFreelanceOutstanding
GROUP BY OrganizationID, ReceivableStatus)
UNION
(SELECT
MAX(OrganizationName) as OrganizationName,
OrganizationID,
'Total' AS ReceivableStatus,
SUM(InvoiceFee) as TotalDue
FROM v_InvoicesFreelanceOutstanding
GROUP BY OrganizationID)
Pivot on this result and you should get the output you want:
SELECT *
FROM
[the query above]
PIVOT (
SUM(TotalDue)
FOR ReceivableStatus IN ([Current],[30-60 days],[60-90 days],[over 90 days],[Total])
)
PIVOT sucks. It has horrible syntax and isn't a PIVOT in the pivot table sense i.e. you have to know exactly how many columns will result in advance.
It's probably easier to do a cross-tab report.
SELECT
OrganizationName,
OrganizationID,
SUM(CASE WHEN ReceivableStatus = '30-60 days' THEN InvoiceFee ELSE 0 END) AS [30 - 60 Days],
SUM(CASE WHEN ReceivableStatus = '60-90 days' THEN InvoiceFee ELSE 0 END) AS [60 - 90 Days],
SUM(CASE WHEN ReceivableStatus = '90-120 days' THEN InvoiceFee ELSE 0 END) AS [90 - 120 Days]
FROM
v_InvoicesFreelanceOutstanding
GROUP BY OrganizationID
I think your are searching for the pivot and unpivot functionality. Take a look at this: http://msdn.microsoft.com/en-us/library/ms177410.aspx
Well, here is another pivot :)
SET NOCOUNT ON DECLARE @table TABLE ( OrganizationName VARCHAR(20), OrganizationID INT, ReceivableStatus VARCHAR(20), InvoiceFee FLOAT ) INSERT INTO @table SELECT 'Company A',139,'60-90 days',672.00 UNION SELECT 'Company A',139,'60-90 days',1800.00 UNION SELECT 'Company A',139,'over 90 days',1440.00 UNION SELECT 'Company B',264,'Current',3559.38 UNION SELECT 'Company B',264,'60-90 days',3785.50 UNION SELECT 'Company C',271,'60-90 days',446.25 UNION SELECT 'Company C',271,'over 90 days',637.50 UNION SELECT 'Company C',271,'over 90 days',1126.25 --Specify Just the fields you want to return ;WITH COMPANYINFO(OrganizationName,OrganizationID,ReceivableStatus,InvoiceFee) AS ( SELECT OrganizationName, OrganizationID, ReceivableStatus, InvoiceFee FROM @Table AS b ) SELECT * FROM COMPANYINFO PIVOT ( SUM(InvoiceFee) FOR ReceivableStatus IN ([Current],[60-90 days],[over 90 days]) ) AS P ORDER BY OrganizationName
I have not used pivot before, so that may be your answer, but I've used brute force on a problem like this in the past and for you it would look something like:
SELECT OrganizationName, SUM(Current) AS Current, SUM(3060Days) AS 3060Days, SUM(6090Days) AS 6090Days, SUM(Over90Days) As Over90Days, SUM(Total) AS Total
FROM
(
SELECT
OrganizationName,
CASE WHEN ReceivableStatus = 'Current' THEN
SUM(InvoiceFee)
ELSE
0
END AS Current,
CASE WHEN ReceivableStatus = '30-60 days' THEN
SUM(InvoiceFee)
ELSE
0
END AS 3060Days,
CASE WHEN ReceivableStatus = '60-90 days' THEN
SUM(InvoiceFee)
ELSE
0
END AS 6090Days,
CASE WHEN ReceivableStatus = 'over 90 days' THEN
SUM(InvoiceFee)
ELSE
0
END AS Over90Days,
SUM(InvoiceFee) AS Total
FROM v_InvoicesFreelanceOutstanding
GROUP BY OrganizationName, ReceivableStatus) temp
GROUP BY OrganizationName
Basically, the inner query gives you results for each organization and a total for each individual category and the outer query aggregates all of them into single rows for each organization. Again, this may not be the most elegant or efficient way to go, but it is a way.