2009-03-20 37 views
5

Tôi có một truy vấn mà trông như thế này:hàng vào Cột và Grouping

SELECT OrganizationName, OrganizationID, ReceivableStatus, InvoiceFee 
FROM v_InvoicesFreelanceOutstanding 
ORDER BY OrganizationID 

Các dữ liệu từ đó có thể trông như thế này:

 
OrganizationName OrganizationID  ReceivableStatus  InvoiceFee 
----------------------------------------------------------------------------- 
Company A      139  60-90 days     672.00 
Company A      139  60-90 days    1800.00 
Company A      139  over 90 days    1440.00 
Company B      264  Current     3559.38 
Company B      264  60-90 days    3785.50 
Company C      271  60-90 days     446.25 
Company C      271  over 90 days    637.50 
Company C      271  over 90 days    1126.25 

Những gì tôi muốn cuối cùng hiển thị là một cái gì đó như thế này (đối với dữ liệu ở trên):

 
Company  Current 30-60 days 60-90 days over 90 days  Total 
----------------------------------------------------------------------------- 
Company A   0    0  2472.00    0  2472.00 
Company B 3559.38    0  3785.50    0  7344.88 
Company C   0    0  446.25   1763.75  2210.00 

My SQL-fu không đủ để tôi vượt qua điều này:

SELECT 
    MAX(OrganizationName) as OrganizationName, 
    OrganizationID, 
    ReceivableStatus, 
    SUM(InvoiceFee) as TotalDue 
FROM v_InvoicesFreelanceOutstanding 
GROUP BY OrganizationID, ReceivableStatus 

nào cho thấy một cái gì đó như thế này (một lần nữa, từ các dữ liệu trên):

 
OrganizationName OrganizationID  ReceivableStatus   TotalDue 
----------------------------------------------------------------------------- 
Company A      139  60-90 days    2472.00 
Company A      139  over 90 days    1440.00 
Company B      264  Current     3559.38 
Company B      264  60-90 days    3785.50 
Company C      271  60-90 days     446.25 
Company C      271  over 90 days    1763.75 

gì sau đó? Bất kỳ trợ giúp sẽ được đánh giá cao.

Lưu ý rằng các trạng thái thể hiện trong bảng 2 (Current, 30-60 days, 60-90 days, over 90 days) là những người duy nhất tôi đang mong đợi để đưa ra dưới ReceivableStatus.

EDIT: Rất tiếc vì không bao gồm điều này. Tôi biết về PIVOT nhưng tôi không thể làm cho nó làm những gì tôi muốn.

Trả lời

2

Điều này trông giống như một công việc cho pivot nếu bạn đang sử dụng SQL Server 2005 trở lên.

EDIT:

Vì bạn đã biết về pivot, bạn biết nó gần như những gì bạn cần.

Bạn đã có truy vấn sau đây:

SELECT 
    MAX(OrganizationName) as OrganizationName, 
    OrganizationID, 
    ReceivableStatus, 
    SUM(InvoiceFee) as TotalDue 
FROM v_InvoicesFreelanceOutstanding 
GROUP BY OrganizationID, ReceivableStatus 

nào mang đến cho bạn hiện nay, 30-60, 60-90 và 90 + bộ phận mà bạn cần. Nếu bạn xoay vòng, bạn sẽ có mọi thứ bạn cần trừ tổng số của bạn. Vì vậy chỉ cần ném vào tổng số:

(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 trên kết quả này và bạn sẽ nhận được kết quả bạn muốn:

SELECT * 
FROM 
    [the query above] 
PIVOT (
    SUM(TotalDue) 
    FOR ReceivableStatus IN ([Current],[30-60 days],[60-90 days],[over 90 days],[Total]) 
) 
+0

tôi cần phải có được rõ ràng hơn; Tôi biết PIVOT, tôi không thể làm được những gì tôi cần. –

+0

Tôi là một moron. Lần đầu tiên tôi tham gia PIVOT là những gì bạn có nhưng tôi đã làm SUM (InvoiceFee) thay vì SUM (TotalDue) trong mệnh đề PIVOT. Boo Hoo. Nó hoạt động, mặc dù. Cảm ơn bạn. –

+0

Tất cả chúng ta đều mắc lỗi. Điều quan trọng là chúng ta học hỏi từ họ. Tôi chỉ vui vì tôi có thể giúp. – Welbog

3

PIVOT hút. Nó có cú pháp khủng khiếp và không phải là PIVOT trong ý nghĩa của bảng tổng hợp, tức là bạn phải biết chính xác có bao nhiêu cột sẽ dẫn trước.

Có thể dễ dàng hơn để thực hiện báo cáo thẻ chéo.

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 
+0

Tuy nhiên, điều này sẽ hoạt động như thế nào với GROUP? Tôi chỉ muốn hiển thị SUM (InvoiceFee) của 30-60 ngày dưới cột 30-60 ngày, v.v. –

+0

Và tôi sẽ biết có bao nhiêu cột sẽ dẫn đến trước, vì vậy tôi ổn với PIVOT nếu nó sẽ hoàn thành công việc, mặc dù cú pháp làm tôi đau đầu. –

1

tôi đã không sử dụng trục trước, vì vậy mà bạn có thể câu trả lời của bạn, nhưng tôi đã sử dụng brute force trên một vấn đề như thế này trong quá khứ và cho bạn nó sẽ giống như thế:

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 

Về cơ bản, truy vấn bên trong cung cấp cho bạn kết quả cho từng tổ chức và tổng số cho từng danh mục riêng lẻ và truy vấn bên ngoài tổng hợp tất cả chúng thành các hàng đơn cho mỗi tổ chức. Một lần nữa, điều này có thể không phải là cách thanh lịch hoặc hiệu quả nhất để đi, nhưng đó là một cách.

+0

+1. Mặc dù nó đã làm việc, nó lớn hơn tôi đã hy vọng và tôi nhận được PIVOT làm việc. Cảm ơn, mặc dù! –

2

Vâng, đây là một trục :)

 
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 
+0

Thực hiện tốt. Cảm ơn bạn. –

Các vấn đề liên quan