0

我有一个数据库来跟踪我们客户的奖励购买。我们的客户进来,进行购买,然后我们将其记录到这个奖励数据库中。当客户满足奖励“发放”的要求(见下文)时,数据库将“发放”奖励给客户。下次客户进行购买时,我们将在我们的数据库中看到 $XX.XX 奖励并将该折扣应用于他们的购买。

我正在努力解决的最大问题是一种方法来实现这一点,即 1)不会减慢数据库速度,2)可以在 db 用户工作时在后台完成。

目前,要求是:

  • 一个日历年内购买六次。
  • 六次购买必须发生在不同的日期。同一天发生的购买记录为同一购买的一部分
  • 这些要求(6 次访问中的 6 次购买)作为选项保留在tblOptions

我正在尝试组装一个程序(每当用户完成一项任务时,我可以在整个数据库中调用一个函数来执行“数学”),以检查n自日历年初以来是否有购买(基于NumVisits& NumPurchasesin tblOptions) 或自上次颁发奖励的日期(此日期在 中qryLastRewardIssuedDate)以来tbPurchases(是的,我意外遗漏了一个“l” - 我稍后会修复它)。

目标:

  • 检索自那时以来已进行了多少次购买qryLastRewardIssued.IssueDate
  • 验证它们是在不同的日子和当前日历年制作的
  • 如果已满足上述要求,则根据中的设置计算其总购买量的百分比tblOptions.PerDiscount

以下是我的人际关系:

表关系

历史:

这开始于我尝试创建一个简单的查询来提取购买数量。我想尝试使用查询来完成此任务,但经过一番思考后,我决定创建一个每次用户执行操作时都可以调用的过程可能会更有效。不幸的是,我的查询并没有为我解决,我在整个过程中都在苦苦挣扎。我对 Access 真的很生疏(从我的 Stack Overflow 历史可以看出),老实说,我对它一开始就不是很好。我有使用 Access 的经验,过去曾设计过多个数据库,但这些都是简单的“将数据放入,稍后查看数据”的数据库。这实际上需要在使用时定期处理数学程序。

由于这开始于一个查询以获取购买数量,因此这是我一直在使用的 SQL 语句(它没有给出错误,但它总是不返回任何结果):

SELECT Count(tbPurchases.MemberID) AS CountOfMemberID, Count(tbPurchases.PurchaseDate) AS NumOfPurchases
FROM tbPurchases INNER JOIN qryLastRewardIssuedDate ON tbPurchases.MemberID = qryLastRewardIssuedDate.CustomerID
HAVING (((Count(tbPurchases.PurchaseDate)) Between [qryLastRewardIssuedDate]![IssueDate] And Now()));

这是我的查询的 SQL qryLastRewardIssuedDate

SELECT tblRewards.CustomerID, Last(tblRewards.IssueDate) AS LastOfIssueDate
FROM tblRewards
GROUP BY tblRewards.CustomerID;

我知道这里没什么可说的,对此我很抱歉。我还没有任何顿悟来引导我朝着正确的方向前进。我希望你们都可以帮助我。谢谢!

编辑: 在玩了一点你的 SQL 语句之后(并修复了评论中提到的别名),这就是我要做的:

SELECT q.MemberID, Max(q.PurchaseDate) AS MaxOfPurchaseDate
FROM (SELECT p.MemberID, p.PurchaseDate FROM tbPurchases p WHERE p.PurchaseDate >= Dateserial(2012,1,1)
  AND p.PurchaseDate > (SELECT Max(r.IssueDate) FROM tblRewards r WHERE r.CustomerID = p.MemberID))  AS q
GROUP BY q.MemberID
HAVING (((Count(*))>=(SELECT Last(o.NumPurchases) AS LastOfNumPurchases FROM tblOptions o)));

这也说明了购买数量的变化。我遇到的一个问题是输出正确的购买成本(tbPurchases.PurchaseAmount)。当我使用此 SQL 时,我在查询中得到相同的结果:

SELECT q.MemberID, Max(q.PurchaseDate) AS MaxOfPurchaseDate, Last(tbPurchases.PurchaseAmount) AS LastOfPurchaseAmount
FROM (SELECT p.MemberID, p.PurchaseDate FROM tbPurchases AS p WHERE p.PurchaseDate >= Dateserial(2012,1,1)       AND p.PurchaseDate > (SELECT Max(r.IssueDate) FROM tblRewards r WHERE r.CustomerID = p.MemberID))  AS q, tbPurchases
GROUP BY q.MemberID
HAVING (((Count(*))>=(SELECT Last(o.NumPurchases) AS LastOfNumPurchases FROM tblOptions o)));

哪个,我认为可能是一个 JOIN 问题,或者可能是我需要别名的事实tbPurchases.PurchaseAmount?我不完全确定。

此外,我现在不完全确定如何验证购买是在不同的日子进行的。有任何想法吗?

编辑 2 - 样本数据:

tblMembers

╔════╦════════════╦═══════════╗
║ ID ║ First Name ║ Last Name ║
╠════╬════════════╬═══════════╣
║  1 ║ Jason      ║ Something ║
║  2 ║ Jimmy      ║ Carter    ║
║  3 ║ Ronald     ║ Reagan    ║
║  4 ║ Ronald     ║ McDonald  ║
╚════╩════════════╩═══════════╝

tblOptions

╔════╦═══════════╦══════════════╦═════════════╗
║ ID ║ NumVisits ║ NumPurchases ║ PerDiscount ║
╠════╬═══════════╬══════════════╬═════════════╣
║  1 ║         6 ║            6 ║ 10.00%      ║
╚════╩═══════════╩══════════════╩═════════════╝

tblRewards

╔════╦════════════╦════════════╦═════════════╦
║ ID ║ CustomerID ║ IssueDate  ║ IssueAmount ║ 
╠════╬════════════╬════════════╬═════════════╬
║  1 ║      24544 ║ 7/22/2011  ║ $100.00     ║
║  2 ║      24557 ║ 6/27/2018  ║ $100.00     ║
║  3 ║      25012 ║ 11/23/2019 ║ $46.63      ║
║  4 ║      28227 ║ 11/11/2019 ║ $40.35      ║
╚════╩════════════╩════════════╩═════════════╩

tbPurchases

╔════╦══════════╦══════════════╦════════════════╗
║ ID ║ MemberID ║ PurchaseDate ║ PurchaseAmount ║
╠════╬══════════╬══════════════╬════════════════╣
║  1 ║    29792 ║ 2/25/2013    ║ $37.99         ║
║  2 ║    24586 ║ 1/3/2019     ║ $114.99        ║
║  3 ║    26505 ║ 1/3/2019     ║ $7.96          ║
╚════╩══════════╩══════════════╩════════════════╝

预期结果: 这里的想法是检查数据库中是否有在当前日历年进行过n购买(从- 目前为 6 个)的客户。tblOptions.NumPurchases数据库中的数据并不多,但我确实添加了一些购买只是为了测试它。

如果当前日历年的购买次数正确,那么它将计算客户在这些n购买上花费的总金额,并使用tblOptions.PerDiscount它来计算客户在下次访问时有权获得的“奖励”金额。

然后是程序进入的时候。我想尝试创建一个可以在整个数据库中完成这些计算的函数。将其添加到其他操作中,例如添加新客户或输入当前客户的购买。而且,最重要的是,当数据库打开和关闭时。这些都可以通过创建一个我可以重复调用的过程来轻松完成。但我无法让这些 SQL 查询合作。

4

1 回答 1

1

首先,不要用于获取Last最新的IssueDate:当与无序数据集一起使用时,Last只会返回数据库引擎在评估查询时遇到的最后一条记录,不一定是数据集中的最后一条记录。

文档中也指出了这一点:

这些函数分别返回查询返回的结果集中的第一条或最后一条记录中指定字段的值。如果查询不包含 ORDER BY 子句,则这些函数返回的值将是任意的,因为记录通常以没有特定顺序返回。

相反,您应该使用来获取每个max的最新信息:IssueDateCustomerID

select
    r.customerid,
    max(r.issuedate) as lastissued
from
    tblrewards r
group by
    r.customerid

对于总体目标,我可能会建议如下查询:

select
    q.memberid
from
    (
        select distinct
            p.memberid,
            p.purchasedate
        from
            tbpurchases p
        where
            p.purchasedate >= dateserial(year(date()),1,1) and
            p.purchasedate >
            (
                select
                    max(r.issuedate)
                from
                    tblrewards r
                where
                    r.customerid = p.memberid
            )
    ) q
group by    
    q.memberid
having
    count(*) >= 6

请注意,以上内容完全未经测试。

于 2020-01-22T18:30:44.860 回答