SQL - 按电子邮件和最新日期分组

Posted

技术标签:

【中文标题】SQL - 按电子邮件和最新日期分组【英文标题】:SQL - Group by email and most current date 【发布时间】:2019-10-01 02:14:44 【问题描述】:

我有一个 SQL 查询,它应该向我显示每位客户的最后一次付款,但它向我显示了所有客户所做的每笔付款。我为此花了一天时间,我即将放弃。我想尝试通过客户电子邮件对我的报告进行分组,然后从每组 customerpayments 中返回每组最近的日期。这应该会在一份报告中向我显示每位客户最近的付款。

我正在从多个表中提取信息。理论上,客户可以拥有相同的姓名、号码或支付相同的金额。但其中唯一的字段是电子邮件。客户也可以升级他们的帐户,因此客户进行的一组付款可能不都是相同的值。因此,如果我们返回最近的日期,它将显示他们当前的最后一次付款。

帮我***,你是我唯一的希望。

SELECT 
    AccountTypes.Name AS AccountType, 
    CONVERT(nvarchar, PaymentHistory.DateCreated, 23) AS Prev_Billing_Date,
    PaymentHistory.Amount AS Amount, 
    Users.FirstName AS FName, 
    Users.LastName AS LName, 
    Users.Phone AS Phone, 
    Users.Email AS Email
FROM 
    AccountTypes 
INNER JOIN 
    Accounts 
INNER JOIN 
    AccountStatus ON Accounts.StatusID = AccountStatus.ID 
INNER JOIN 
    PaymentHistory ON Accounts.ID = PaymentHistory.AccountID 
            ON AccountTypes.ID = Accounts.AccountTypeID 
INNER JOIN 
    Users 
INNER JOIN 
    UserAccounts ON Users.ID = UserAccounts.UserID 
            ON Accounts.ID = UserAccounts.AccountID
WHERE 
    (UserAccounts.IsOwner = 1) AND 
    (AccountStatus.Name = 'Paid') AND 
    (Accounts.AccountTypeID = 2 OR 
     Accounts.AccountTypeID = 3 OR 
     Accounts.AccountTypeID = 4 OR 
     Accounts.AccountTypeID = 5)
GROUP BY
    AccountTypes.Name, 
    PaymentHistory.DateCreated,
    PaymentHistory.Amount, 
    Users.FirstName, 
    Users.LastName, 
    Users.Phone, 
    Users.Email
ORDER BY 
    AccountType DESC, Email, Prev_Billing_Date DESC;

【问题讨论】:

【参考方案1】:

您可以使用row_number()partition by 来实现您想要的。你不需要使用GROUP BY,因为你没有使用任何聚合函数。

SELECT t1.* FROM 
    (SELECT 
        AccountTypes.Name AS AccountType, 
        CONVERT(nvarchar, PaymentHistory.DateCreated, 23) AS Prev_Billing_Date,
        PaymentHistory.Amount AS Amount, 
        Users.FirstName AS FName, 
        Users.LastName AS LName, 
        Users.Phone AS Phone, 
        Users.Email AS Email,
        ROW_NUMBER() over (PARTITION BY Users.Email ORDER BY PaymentHistory.DateCreated DESC) as rn
    FROM AccountTypes 
    INNER JOIN Accounts ON AccountTypes.ID = Accounts.AccountTypeID 
    INNER JOIN AccountStatus ON Accounts.StatusID = AccountStatus.ID 
    INNER JOIN PaymentHistory ON Accounts.ID = PaymentHistory.AccountID                     
    INNER JOIN UserAccounts ON Accounts.ID = UserAccounts.AccountID
    INNER JOIN Users ON Users.ID = UserAccounts.UserID      
    WHERE 
        UserAccounts.IsOwner = 1 AND 
        AccountStatus.Name = 'Paid' AND 
        Accounts.AccountTypeID IN (2,3,4,5)
    ) t1
WHERE t1.rn = 1
ORDER BY 
    t1.AccountType DESC, t1.Email, t1.Prev_Billing_Date DESC;

【讨论】:

成功了!!!我真的很想学这个。你能用“t1”解释一下吗?我以前没见过这种方法。我对 SQL 真的很陌生。几年前我上过一堂课,所以我记得基础知识。我将研究使用行号和分区依据。非常感谢您对此进行尝试。现在我终于可以上床睡觉了。 t1 只是子查询的表别名。可以检查这个链接。 docs.microsoft.com/en-us/sql/relational-databases/performance/…

以上是关于SQL - 按电子邮件和最新日期分组的主要内容,如果未能解决你的问题,请参考以下文章

SQL 检索最新记录,按唯一外键分组

sql 从2个不同的表中选择唯一的电子邮件,并按日期排序。

删除重复行但保留最早的行(按日期标准) - SQL Server

MySQL 按 ID 和最新日期时间分组

我需要连接三个表,将结果按一列分组,并显示另一列的最大值

如何按一列的最大值获取SQL行,按另一列分组