2015-01-09 5 views
0

У меня есть этот запросSQL Server: агрегат для одного результата

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 

Как я могу изменить свой запрос, чтобы достичь этого?

UPDATE Благодаря jarlh за ответ, но я пропустил что-то - если есть повторяющиеся строки - он будет оставаться в результате, глядя, как это:

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

Любой способ сделать это Работа?

ответ

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

Спасибо за ответ, но я забыл упомянуть о возможности дублированных результатов, поясняются в обновлении – Caballero

+0

Просто добавил DISTINCT в ваш запрос, и теперь он работает как положено. – Caballero

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

Спасибо за ответ, но мне нужно сжать это в обычный запрос, потому что мне придется перевести его в запрос Slick FRM. Возможно ли это вообще? – Caballero

+0

@Caballero: Все возможно. Это немного неудобно. Я обновляю ответ – Arion

+0

Последний пробный прогон для меня будет переменным, я не думаю, что можно избавиться от них, не выдувая этот запрос из пропорции? – Caballero

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 
Смежные вопросы