SQL Server:聚合到单个结果

时间:2015-01-09 09:36:40

标签: sql sql-server greatest-n-per-group

我有这个查询

SELECT      Client.ClientNo,
            Client.ContactName,
            Deal.Currency,
            MAX(Deal.DealDate)
FROM        Deal
JOIN        Client ON Deal.ClientNo = Client.ClientNo
GROUP BY    Client.ClientNo, Client.ContactName, Deal.Currency;

给了我一个结果

1   John Smith  EUR 2014-10-07
1   John Smith  GBP 2014-11-12
2   Jane Doe    GBP 2014-09-17
2   Jane Doe    USD 2014-12-23
1   John Smith  USD 2013-11-13
2   Jane Doe    EUR 2012-09-06

问题是,我需要一个汇总结果,每个客户的最新日期,如下所示:

1   John Smith  GBP 2014-11-12
2   Jane Doe    USD 2014-12-23

如何更改查询以实现此目的?

更新感谢jarlh的答案,但是我错过了一些东西 - 如果有重复的行 - 它会保留在结果中,如下所示:

1   John Smith  GBP 2014-11-12
1   John Smith  GBP 2014-11-12
2   Jane Doe    USD 2014-12-23

任何使这项工作的方法?

3 个答案:

答案 0 :(得分:3)

你可以这样做:

测试数据:

DECLARE @Deal TABLE(ClientNo INT,Currency VARCHAR(10),DealDate DATETIME)
DECLARE @Client TABLE(ClientNo INT,ContactName VARCHAR(100))

INSERT INTO @Deal
VALUES (1,'EUR','2014-10-07'),(1,'GBP','2014-11-12'),(2,'GBP','2014-09-17'),
(2,'USD','2014-12-23'),(1,'USD','2013-11-13'),(2,'EUR','2012-09-06')

INSERT INTO @Client
VALUES (1,'John Smith'),(2,'Jane Doe')

<强>查询:

;WITH latestDeals
AS
(
    SELECT
        ROW_NUMBER() OVER(PARTITION BY ClientNo ORDER BY DealDate DESC) AS RowNbr,
        Deal.*
    FROM
        @Deal AS Deal
)
SELECT
    client.ClientNo,
    client.ContactName,
    latestDeals.Currency,
    latestDeals.DealDate
FROM
    @Client AS client
    JOIN latestDeals
        ON client.ClientNo=latestDeals.ClientNo
        AND latestDeals.RowNbr=1

<强>更新

如果要使用常规查询。你可以这样做:

SELECT
    client.ClientNo,
    client.ContactName,
    Latestdeal.maxDealDate as DealDate,
    deal.Currency
FROM
    @Client AS client
    JOIN 
    (
        SELECT
            MAX(Deal.DealDate) AS maxDealDate,
            Deal.ClientNo
        FROM
            @Deal AS Deal
        GROUP BY
            Deal.ClientNo
    ) AS Latestdeal
    ON client.ClientNo=Latestdeal.ClientNo
    JOIN @Deal as deal
        ON client.ClientNo=deal.ClientNo
        AND deal.DealDate=Latestdeal.maxDealDate

这将产生相同的输出

<强>结果:

1   John Smith  GBP 2014-11-12 00:00:00.000
2   Jane Doe    USD 2014-12-23 00:00:00.000

答案 1 :(得分:1)

未经测试,但应该有效。如果客户端有两个(或更多)交易相同,最近一天,将为客户返回多行。

SELECT      Client.ClientNo,
            Client.ContactName,
            Deal.Currency,
            Deal.DealDate
FROM        Deal
JOIN        Client ON Deal.ClientNo = Client.ClientNo
WHERE       Deal.DealDate = (select max(DealDate) from Deal
                             where ClientNo = Client.ClientNo)

答案 2 :(得分:0)

试试这个,

测试数据:

CREATE TABLE #YourTable
(
    CLIENT_NO INT,
    CONTACT_NAME VARCHAR(20),
    CURRENCY VARCHAR(10),
    [DEAL_DATE] DATE
)

INSERT INTO #YourTable VALUES
(1,'John Smith','EUR','2014-10-07'),
(1,'John Smith','GBP','2014-11-12'),
(2,'Jane Doe','GBP','2014-09-17'),
(2,'Jane Doe','USD','2014-12-23'),
(1,'John Smith','USD','2013-11-13'),
(2,'Jane Doe','EUR','2012-09-06')

查询:

SELECT CLIENT_NO,CONTACT_NAME,CURRENCY,[DEAL_DATE]
FROM   (SELECT *,
               Row_Number()
                 OVER (
                   PARTITION BY CLIENT_NO
                   ORDER BY [DEAL_DATE] DESC) AS RN
        FROM   #YourTable)A
WHERE  RN = 1