2009-05-01 121 views
2

我有一个订单表(简体)总和不同行中列基于第二列的值

OrderId, 
SalesPersonId, 
SaleAmount, 
CurrencyId, 
... 

我试图创建该表的报表,我希望这样的事情:

SalesPersonId TotalCAD TotalUSD 
1    12,345.00 6,789.00 
2    7,890.00 1,234.00 

我不想做一个自连接(也许我过早的优化,但是这似乎效率不高),即:

SELECT SalesPersonId, SUM(OrdersCAD.SaleAmount), SUM(OrderUSD.SaleAmount) 
FROM Orders 
    LEFT JOIN Orders AS OrdersCAD ON Orders.OrderID AND Orders.CurrencyID = 1 
    LEFT JOIN Orders AS OrdersUSD ON Orders.OrderID AND Orders.CurrencyID = 2 

但我想不出另一种方式来做到这一点,有什么想法?

回答

7

使用CASE块:

SELECT 
    SalesPersonId, 
    SUM(
    CASE CurrencyID 
     WHEN 1 THEN SaleAmount 
     ELSE 0 
    END 
) AS TotalCAD, 
    SUM(
    CASE CurrencyID 
     WHEN 2 THEN SaleAmount 
     ELSE 0 
    END 
) AS TotalUSD 
FROM Orders 
GROUP BY SalesPersonId 
+0

简直太棒了。我有一段时间想知道如何做到这一点。谢谢。 – LittleTreeX 2010-12-20 15:19:55

2

试试这个:

SELECT SalesPersonId, 
     SUM(CASE WHEN CurrencyID = 1 THEN SaleAmount ELSE 0 END) as CAD, 
     SUM(CASE WHEN CurrencyID = 2 THEN SaleAmount ELSE 0 END) as USD 
FROM ORDERS 
0

考虑尝试一个标量值函数(SQL Server 2000或更高版本)。

CREATE FUNCTION dbo.GetOrdersSumByCurrency 
( 
    @SalesPersonID INT, @CurrencyID INT 
) 
RETURNS DECIMAL(10, 2) 
AS 
BEGIN 
    DECLARE @Sum DECIMAL(10, 2) 

    SELECT @Sum = ISNULL(SUM(SalesAmount), 0) FROM dbo.Orders 
    WHERE [email protected] AND CurrencyID = @CurrencyID 

    RETURN @Sum 

END 

然后执行SQL像这样得到的结果(假设你也有一个单独的销售人员表,或以其它方式使用,而不是SELECT DISTINCT SalesPersonId ....从接单):

SELECT SalesPersonId, 
dbo.GetOrdersSumByCurrency(SalesPersonId, 1) AS SumUSD, dbo.GetOrdersSumByCurrency(SalesPersonId, 2) AS SumCAD 
    FROM SalesPersons 

要确保运行查询计划,以查看它是否与您在此处提出的其他可能性相比所需的性能,特别是在处理大量数据时。