简体   繁体   中英

Choose column based on max() of another column

Given the data below from the two tables cases and acct_transaction, how can I include just the acct_transaction.create_date of the largest acct_transaction amount whilst also calculating the sum of all amounts and the value of the largest amount? Platform is t-sql.

id  amount     create_date  
---|----------|------------|
1  | 1.99     | 01/09/2009 | 
1  | 2.99     | 01/13/2009 | 
1  | 578.23   | 11/03/2007 | 
1  | 64.57    | 03/03/2008 | 
1  | 3.99     | 12/12/2012 | 
1  | 31337.00 | 04/18/2009 | 
1  | 123.45   | 05/12/2008 | 
1  | 987.65   | 10/10/2010 | 

Result set should look like this:

id  amount     create_date  sum        max_amount  max_amount_date
---|----------|------------|----------|-----------|-----------
1  | 1.99     | 01/09/2009 | 33099.87 | 31337.00  | 04/18/2009
1  | 2.99     | 01/13/2009 | 33099.87 | 31337.00  | 04/18/2009
1  | 578.23   | 11/03/2007 | 33099.87 | 31337.00  | 04/18/2009
1  | 64.57    | 03/03/2008 | 33099.87 | 31337.00  | 04/18/2009
1  | 3.99     | 12/12/2012 | 33099.87 | 31337.00  | 04/18/2009
1  | 31337.00 | 04/18/2009 | 33099.87 | 31337.00  | 04/18/2009
1  | 123.45   | 05/12/2008 | 33099.87 | 31337.00  | 04/18/2009
1  | 987.65   | 10/10/2010 | 33099.87 | 31337.00  | 04/18/2009

This is what I have so far, I just don't know how to pull the date of the largest acct_transaction amount for max_amount_date column.

SELECT      cases.id,  acct_transaction.amount, acct_transaction.create_date AS 'create_date',  SUM(acct_transaction.amount) OVER () AS 'sum', MIN(acct_transaction.amount) OVER () AS 'max_amount'
FROM        cases INNER JOIN
            acct_transaction ON cases.id = acct_transaction.id
WHERE       (cases.id = '1') 
;WITH x AS 
(
  SELECT c.id, t.amount, t.create_date, 
    s = SUM(t.amount) OVER(), 
    m = MAX(t.amount) OVER(),
    rn = ROW_NUMBER() OVER(ORDER BY t.amount DESC)
   FROM dbo.cases AS c
   INNER JOIN dbo.acct_transaction AS t
   ON c.id = t.id
)
SELECT x.id, x.amount, x.create_date,
   [sum] = y.s,
   max_amount = y.m, 
   max_amount_date = y.create_date
FROM x CROSS JOIN x AS y WHERE y.rn = 1;

You can just do a full outer join to the table which defines the aggregates:

select id, amount, create_date, x.sum, x.max_amount, x.max_amount_date
from table1
full outer join 
(select sum(amount) as sum, max(amount) as max_amount, 
   (select top 1 create_date from table1 where amount = (select max(amount) from table1)) as max_amount_date
 from table1) x
on 1 = 1 

SQL Fiddle demo

Try this abomination of a query... I make no claims for its speed or elegance. It's likely I should pray that Cod have mercy on my soul.

Here is the out put of a join on the two tables that you mention but for which you do not provide schemas.

[SQL Fiddle][1]

SELECT A.case_id
 ,A.trans_id
 ,A.trans_amount
 ,A.trans_create_date
 ,A.trans_type
 ,B.max_amount
 ,B.max_amount_date
 ,E.sum_amount
FROM acct_transaction AS A
INNER JOIN (select C.case_id
 ,MAX(C.trans_amount) AS max_amount
 ,C.trans_create_date AS max_amount_date 
 FROM acct_transaction AS C group by C.case_id, C.trans_create_date ) AS B ON B.case_id = A.case_id
inner JOIN (select D.case_id, SUM(D.trans_amount) AS sum_amount FROM acct_transaction AS D GROUP BY D.case_id) AS E on E.case_id = A.case_id
WHERE (A.case_id = '1') AND (A.trans_type = 'F')
GROUP BY A.case_id

Thanks, that got me on the right track to this which is working:

,CAST((SELECT TOP 1 t2.create_date from acct_transaction t2 
            WHERE t2.case_sk = act.case_sk AND (t2.trans_type = 'F')
            order by t2.amount, t2.create_date DESC) AS date) AS 'max_date'

It won't let me upvote because I have less than 15 rep :(

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM