SQL - 营业时间
我很难理解一个看似简单的问题。假设我有一家公司,每天的营业时间为中午 12 点至凌晨 3 点。每个客户每天都会根据当天的首次购买获得一次奖金。因此,假设他们当天的第一笔交易花费了 20 美元——他们可能会在该交易中获得 20% 的折扣,仅此而已。
我正在尝试找出最准确的方法来检查上次发放的奖金,并确保客户有资格获得奖金。显然,我无法进行简单的 24 小时检查,因为例如,如果客户在周一晚上 11 点进来,然后在周二中午再次进来,他们将不会获得第二笔奖金。
我们的 POS 使用 VB6 前端,并使用 SQL Server 2008 R2 数据库。每次应用奖金时,都会在数据库端进行审核,因此我可以轻松查询上次应用奖金的时间。
编辑:我应该注意,由于各种原因,解决方案不能包括对数据库结构进行任何更改。
I'm having a hard time wrapping my head around what seems to be a somewhat simple issue. Let's say that I have a business whose hours are 12PM - 3AM daily. Each customer gets a bonus once per day based on their initial purchase for that day. So, let's say they spend twenty bucks on their first transaction that day -- they might get a twenty percent discount on that transaction, and that's it for the day.
I'm trying to figure out the most accurate way to check the last bonus that was given and make sure that the customer is eligible for one. I can't do a simple 24-hour check, obviously, because if a customer comes in at 11 PM Monday, for instance, and again at noon Tuesday, they will not get their second bonus.
We are using a VB6 frontend for our POS, with a SQL Server 2008 R2 database. Each time a bonus is applied, it is audited on the database side, so I can easily query the last time the bonus was applied.
EDIT: I should note that, for various reasons, the solution cannot include making any changes to the structure of the database.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我不确定您想要在哪一方(VB 或 SQL)应用业务逻辑,但在任何一种情况下,过程都应该是相同的:您需要使用两个属性来保存每个客户的每日操作时间:
,您检查交易时间是否在
Time
和Time + TimeSpan
之间,以计算您的业务逻辑和客户的奖金。这两种计算在 VB 和 SQL 中都相当简单。您只需要确保以逻辑方式保留数据并一致地使用它。I'm not sure on which side (VB or SQL) you want to apply the biz logic but in either case the process should be the same: You need to persist each customer's daily hours of operation with two attributes:
You then check if a transaction's time is between
Time
andTime + TimeSpan
to calculate your business logic and the customer's bonus. Both calculations are fairly trivial in VB and SQL. You just need to make sure you persist the data logically and use it consistently.我认为如果您将其修改为以下内容,您的答案会更清晰:
您根据添加到最后奖金的日期部分的固定时间来计算商店的营业和关闭日期。像
然后添加时间跨度(如建议的那样)以获得关闭时间。这可能有点棘手,因为如果是在午夜之后,则需要将开放时间添加到前一个日期,但您可能可以使用
CASE
语句来解决此问题。如果我的宝宝没有耳朵感染,我会自己尝试一下。希望这对您有用。I think your answer would be cleaner if you modified it to something like:
where you figure the store open and close dates based on a fixed times that are added to the date part of the last bonus. Something like
And then adding the timespan (as was suggested) to get the close time. It might be a little tricky because if it's after midnight, the open time would need to be added to the previous date instead, but you could probably work this out with a
CASE
statement. I'd try it out myself if my baby didn't have an ear infection. Hope that is useful to you.怎么样:
lastBonusTime 是最后一次奖金交易的时间?
How about:
Where lastBonusTime is the time of the last bonus transaction ?
你可以稍微不同地看待这个问题。如果客户现在在这里 (
GETDATE()
),距上次购买是否已超过 24 小时?所以,
我也会考虑数据的细节——上面的内容根本没有针对性能进行调整。我只是想解释一下我的思维过程。
You can look at the problem a bit differently. If a customer is here now (
GETDATE()
), has it been over 24 hours since their last purchase?So, something like
I would also consider the specifics of the data--the above is NOT TUNED FOR PERFORMANCE AT ALL. I just wanted to explain my thought process.
为了区分您的担忧,我将添加一个新表,例如
CUSTOMER_BONUS
,其中包含以下列:当您为客户申请一天的奖金时,请在该表中写入一条新记录它适用的时期。此表中存在记录表示客户没有资格在
BonusStart
和BonusEnd
之间获得其他奖金。当您创建新销售时,请查看此表。如果记录存在,则没有奖金,但如果不存在,则应用奖金并在此处创建新记录。In the interest of separating your concerns, I would add a new table, like
CUSTOMER_BONUS
, with these columns:When you apply a bonus for a customer for a day, write a new record into this table for the period that it applies to. Presence of a record in this table indicates that the customer is not eligible for another bonus between
BonusStart
andBonusEnd
. When you create a new sale, look in this table. If the record exists, no bonus, but if not, apply the bonus and create a new record here.我想出了一个令我满意的答案,但它有点笨拙,如果提供一个更优雅的答案,我将非常乐意接受。另外,我还没有彻底测试过这个,因为已经很晚了,但是如果我的逻辑有缺陷,我会很乐意修改或接受修改后的答案。
基本上,我只是要确定以工作日计算的一周中的哪一天是四小时前开始的任何一天。这意味着,一直到凌晨 3:59,“今天”将被视为前一天,这对于这些运营时间来说是正确的(我超出了凌晨 3 点的关闭时间,以考虑到网站决定保持开放状态)稍后)。然后,我使用相同的规则将此时间跨度与最近一次向该客户的帐户应用奖金的时间进行比较。如果两者匹配,则奖金已在本工作日应用。如果不同,则说明没有,并且客户符合资格。
如果我将其放入存储过程中,我可以简单地向其中放入一个客户 ID,并让它吐出一点,如果客户符合条件,则显示 1,否则显示 0。我不喜欢的是,如果客户的营业时间提前了很多,我就会陷入困境(我猜大约是上午 7:00,此时简单地减去四个小时就会与前一个工作日重叠,但减去较少的金额不足以达到前一个工作日)。所以它暂时有效,但我很想看到更好的解决方案。
I came up with an answer that I'm content with but it's a little kludgy and I would be more than happy to accept a more elegant answer if one is provided. Also, I haven't thoroughly tested this since it's getting late in the day, but if there are flaws in my logic, I will happily revise or accept an answer with revisions.
Basically, I'm just going to determine that the day of the week in terms of a business day is whatever day started four hours ago. This means that all the way up through 3:59 AM, "today" will be considered the day before, which is correct for these hours of operation (I'm overshooting the 3 AM closing time to account for a site deciding to stay open a little later). I then compare this span of time to the most recent time a bonus was applied to that customer's account, using the same rules. If the two match, the bonus has been applied this business day. If they are different, it has not, and the customer is eligible.
If I throw this in a stored procedure, I can simply throw a customer ID at it and have it spit out a bit that will show me 1 if the customer is eligible, 0 otherwise. What I don't like about it is that if a customer's hours of operation end up getting much earlier, I'll be sunk (I guess at about 7:00 AM, when simply subtracting four hours will overlap into the previous business day, but subtracting less will not be enough to reach the previous business day). So it will work for the time being, but I'd love to see a better solution.