行进入列和分组

时间:2009-03-20 14:24:29

标签: sql sql-server

我有一个如下所示的查询:

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

来自的数据可能如下所示:

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

我想最终显示的是这样的(对于上面的数据):

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

我的SQL-fu还不足以让我超越这个:

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

其中显示的内容(再次,来自上面的数据):

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

然后呢?任何帮助将不胜感激。

请注意,第二个表格中显示的状态(Current30-60 days60-90 daysover 90 days)是我唯一期望ReceivableStatus {1}}。

编辑:很抱歉不包括此内容。我知道PIVOT但我无法做到我想做的事。

5 个答案:

答案 0 :(得分:5)

PIVOT很糟糕。它具有可怕的语法,并且在枢轴表意义上不是PIVOT,即您必须确切地知道将提前产生多少列。

进行交叉表报告可能更容易。

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

答案 1 :(得分:3)

如果您使用的是SQL Server 2005或更高版本,这看起来像pivot的作业。

编辑:

由于您已经了解pivot,因此您知道它几乎可以满足您的需求。

您已经有以下查询:

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

为您提供所需的30-60,60-90和90+部件。如果您转动它,除了总数之外,您将获得所需的一切。所以只需投入总数:

(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)

转动此结果,您应该获得所需的输出:

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

答案 2 :(得分:2)

我以前没有使用过枢轴,所以这可能是你的答案,但我过去曾对这样的问题使用蛮力,对你来说它看起来像是:

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

基本上,内部查询为每个组织提供结果,为每个单独的类别提供总计,外部查询将所有这些结果聚合为每个组织的单行。同样,这可能不是最优雅或最有效的方式,但这是一种方式。

答案 3 :(得分:2)

嗯,这是另一个支点:)

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

答案 4 :(得分:0)

我认为您正在搜索pivot和unpivot功能。 看看这个:http://msdn.microsoft.com/en-us/library/ms177410.aspx