Max date won't work, alternative?

你。 提交于 2019-12-13 03:39:44

问题


I read through some of the answers but couldn't find the right answer for the following question. I have the below query that runs:

SELECT 
    mbr_src_code as 'C',
    cst_recno as 'ID',
    ind_first_name as 'FN',
    ind_last_name as 'LN',
    cst_org_name_dn as 'Company',
    cst_ixo_title_dn as 'Title',
    MAX(inv_trx_date) as 'Latest Transaction',
    inv_add_user as 'User',
    pyd_type as 'Type',
    bat_code as 'Code',
    mbr_add_user 'Add User',
    mbr_rejoin_date as 'rejoin',
    mbt_code,
    adr_state as 'state',
    adr_country as 'country',
    ivd_amount_cp
FROM 
    mb_membership  
JOIN 
    co_customer ON cst_key = mbr_cst_key AND mbr_delete_flag = 0  
LEFT JOIN 
    mb_member_type ON mbr_mbt_key = mbt_key 
LEFT JOIN 
    co_customer_x_address ON cxa_key = cst_cxa_key 
LEFT JOIN 
    co_address ON cxa_adr_key = adr_key 
LEFT JOIN 
    co_individual ON ind_cst_key = cst_key 
LEFT JOIN 
    mb_membership_x_ac_invoice ON mxi_mbr_key = mbr_key 
LEFT JOIN  
    ac_invoice ON mxi_inv_key = inv_key 
LEFT JOIN 
    ac_invoice_detail ON ivd_inv_key = inv_key 
LEFT JOIN 
    ac_payment_detail ON pyd_ivd_key = ivd_key 
LEFT JOIN 
    ac_payment ON pyd_pay_key = pay_key 
LEFT JOIN 
    ac_batch ON pay_bat_key = bat_key 
LEFT JOIN 
    ac_payment_info ON pay_pin_key = pin_key
LEFT JOIN 
    co_customer_x_customer ON cxc_cst_key_1 = co_customer.cst_key 
                           AND (cxc_end_date IS NULL OR DATEDIFF(dd, GETDATE(), cxc_end_date) >= 0) 
                           AND cxc_rlt_code = 'Chapter Member' 
LEFT JOIN 
    co_chapter ON cxc_cst_key_2 = chp_cst_key  
WHERE 
    (mbr_src_code LIKE N'%1DMFY18%' OR mbr_src_code LIKE N'%2DMFY18%' 
     OR mbr_src_code LIKE N'%INPhoneFY18%' OR mbr_src_code LIKE N'%OBTMFY18%' 
     OR mbr_src_code LIKE N'%3DMFY18%') 
    AND cst_recno = '20239'
GROUP BY  
    mbr_key, mbr_src_code, cst_recno, 
    ind_first_name, ind_last_name, cst_org_name_dn, cst_ixo_title_dn,
    inv_add_user, pyd_type, bat_code, mbr_add_user, mbr_rejoin_date,
    mbt_code, adr_state, adr_country, pin_cc_number_display, pin_cc_cardholder_name,
    ivd_amount_cp, chp_name
ORDER BY
    ind_last_name

and I get the following result(sample):

      C       ID    FN    LN       Company          Title       Latest transaction     User              Type          Code                    Add User    rejoin   mbt_code           state  country    ivd_amount_cp     
    2DMFY18 20239   Gus Bauman  Beveridge & Diamond Attorney    2013-09-23 00:00:00 Membership Renewal  Payment 2013-09-23-ULI-USD-C-SP-01  ULI_Conversion  NULL    Associate Member    DC  UNITED STATES   430.00  
    2DMFY18 20239   Gus Bauman  Beveridge & Diamond Attorney    2014-08-04 00:00:00 Membership Renewal  Payment 2014-08-04-ULI-USD-C-SP-01  ULI_Conversion  NULL    Associate Member    DC  UNITED STATES   430.00  
    2DMFY18 20239   Gus Bauman  Beveridge & Diamond Attorney    2015-09-02 00:00:00 Membership Renewal  Payment 2015-09-02-ULI-USD-C-SP-02  ULI_Conversion  NULL    Associate Member    DC  UNITED STATES   440.00  
    2DMFY18 20239   Gus Bauman  Beveridge & Diamond Attorney    2016-09-12 00:00:00 Membership Renewal  Payment 2016-09-12-ULI-USD-C-SP-01  ULI_Conversion  NULL    Associate Member    DC  UNITED STATES   440.00  
    2DMFY18 20239   Gus Bauman  Beveridge & Diamond Attorney    2017-09-22 00:00:00 Membership Renewal  Payment 2017-09-22-ULI-USD-C-SP-01  ULI_Conversion  NULL    Associate Member    DC  UNITED STATES   440.00

So my MAX function doesn't work(probably because there are other columns with different value,just like in inv_trx_date) , what would be the best alternative to use? I would like to basically take the whole query and select MAX(inv_trx_date) as 'Latest Transaction' per each unique cst_recno as 'ID'.


回答1:


I think the canonical answer to this question is as follows

with AllData as
(
select ... from ...
where ...
)
select * from allData ad1
inner join 
(
    select pk1, pk2, pk<n>, max(MaxThing) MaxVal 
    from AllData
    group by pk1, pk2, pk<n>
) as ad2 
on (ad1.pk1=ad2.pk1 and ad1.pk2=ad2.pk2 and ad1.pk<n>=ad2.pk<n> 
and  ad1.MaxThing=ad2.MaxVal)

In your case cst_recno is the PK and inv_trx_date is the MaxThing




回答2:


MAX works over the entire group you have specified. If you want the MAX aggregation to work for each unique cst_recno then you need to group by only each unique cst_recno.




回答3:


The issue of duplicate rows is because your CODE and ivd_amount_cp columns contain non-unique values in the recordset. Had they all contained the exact same information, your MAX function would have worked without any problems.

You will have to use a Common Table Expression, as others have suggested. Let's assume you have a table that contains a specific CustomerID, and order dates, as well as a lot of other information. A customer can place multiple orders on the same date, and for whatever reason, we're only interested in the latest order of that customer. However, we do want to see all information related to that order.

The first thing we do is build a CTE to identify which order is the latest:

/* Example table */
CREATE TABLE myOrders
(
    OrderID int IDENTITY(1,1)
    , CustomerID int 
    , OrderDate datetime
    , ImportantInfo nvarchar(255)
)
;

/* Some test data to work with */
INSERT INTO myOrders 
VALUES (
    1, '01-01-2017', 'We do not want this row'
), (
    1, '01-02-2017', 'We do not want this row either'
),  (
    1, '01-10-2017', 'Getting closer, but not this one either'
),  (
    1, '01-10-2017', 'This is the one we want!'
)
;

WITH myMaxOrder AS 
(
    SELECT CustomerID, MAX(OrderID) AS MaxOrderID
    FROM myORders
    GROUP BY CustomerID
)

Once you identified the MAX of whatever you need, you then simply use that to identify all the other data you want to retrieve, by using the CTE to join back to the original table using the values you just obtained in the CTE:

SELECT 
    o.* 
FROM 
    MyOrders o
    JOIN myMaxOrder o1 ON o.CustomerID = o1.CustomerID 
    AND o1.MaxOrderID = o.OrderID


来源:https://stackoverflow.com/questions/46671164/max-date-wont-work-alternative

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!