SQL Database Design for monthly issued coupons - sql

I'm struggling with a database schema for a problem I'm having.
Let's say I own a business that sells monthly services (cleaning) to different companies.
However, I give companies monthly saveable 'coupons' that act like a reduction (of 5 dollars) based on their amount of users.
Example:
It's april 2018
Company XYZ has to pay 1.000 dollars for their monthly cleaning services by my business.
XYZ, has 5 employees, so they will have 5 coupons for the month of april.
HOWEVER, since coupons can be saved (for a period of 2 months), company XYZ will not use the coupons of only april, but also of march (since they didn't use any that month and february coupons are already used up).
Result:
10 coupons are used on their april invoice (5 of march, 5 of april):
total amount to pay 950 dollars
My thing is that I want to automate this. With one click on the button, my system will have to check:
How many users there are
If there are any unused coupons from last 2 months (and use those first if they exist)
Apply coupons to their invoice.
I want to design this first in a database but i'm struggling:
This is my design
Company
CompanyID
Name
User
UserID
CompanyID
UserID
Now I'm struggling with the coupon design, how can I develop this so that I can automise my problem.
I will need to save coupons per company per month.
My idea is to do it like this:
Company_Month_Coupon
CompanyID
Coupon_Count
Month
I wasn't sure if i could do this in one table and i'm not so sure with the following problem:
what if my program user decides to cancel an invoice, how would my system know from which month the coupons came?
What design would be adviced in a coupon-sharing system?
Any advice to tackling this problem would greatly appreciated.

I would go with your idea and have 2 more tables: Invoices and Invoices_UsedCoupons
Invoices:
ID (Primary key)
CompanyID
Month
Status (to set a cancelled status on your invoice if you don't want to delete from the DB)
Invoices_UsedCoupons:
InvoiceId (foreign key to Invoices table)
Coupon_Count
Month (this field is for the used coupons from Company_Month_Coupon table)
The reasons for this:
We should still store the issued coupons (in your Company_Month_Coupon table) because for each month, the number of employees may change. It means that you have to keep track of the issued coupons whenever the number of employees changes.
With Invoices and Invoices_UsedCoupons table, you could easily calculate the actual used coupons & the remaining coupons.
what if my program user decides to cancel an invoice, how would my
system know from which month the coupons came?
All the information is available in Invoices and Invoices_UsedCoupons tables. If you want to reclaim coupons after cancelling the invoice, it's also easy to do.

"I will need to save coupons per company per month."
Maybe you can do the opposite. In the database does not store coupons that can be used, but only those that are actually used, for example in the table "used_coupons"
The idea is that the coupons are given up by default, so it makes no sense to store them. Only need to save the used coupons.
At checkout you need to find out how much users is in the company and how many "used coupons" is saved in the last two months.
If X coupons are returned then from the "used_coupons" table you need to delete the latest X coupons.

Related

Zoho Reports: SQL Query - Finding date and number of days

Problem Statement: I need to find out Over Due start date and from that i need to calculate number of Over due days. I know how to do for Over due days count, but i am not able to find a way to figure out for Over due start date.
Example: Let us say a customer did not pay for 4th November 2017, 4th December 2017, 4th Jan 2018, 4th Feb 2018. Now for these There were 4 Zero collection records placed in Collections table and 4 records placed in Over Due Collections table with D Flag. Now on 8th Feb Customer Paid an installment then the respective payment record has been placed in Collections table and another record in Over due collections with C flag. Since this payment gets adjusted for 4th November 2017 the Over due start date will be 4th December. Suppose if the customer did not pay then it will be 4th November 2017 as the Over due start date.
I have tables as follows for a Loan Management System:
Schedule (Payment Schedule): Which will have all the Installments, with the dates adn the respective amounts to be paid for each month.
Schema: LoanNo, Schedule Date, Installment No, Principle, Interest.
Collections (Payment Collections) for each month which has been collected. Suppose if the payment not received, A record placed with the respective date and with Zero amount. and another record will be placed in Over due collections table with D flag with the respective amounts. If there is any collection happens, then another record will be inserted with the flag C which represents collections.
Schema: LoanNo, PaymentReceived Date, Principle, Interest
Over Due Collections (Which there will be a record placed if there is a Due)
Schema: LoanID, Flag(D/C), Date, Principle, Interest
Please do suggest and guide me to write a proper query for this
it's interesting yet easy problem. you can tackle by calculating running sum of the amount and then compare with total payments by the customer. Take all the records having running sum greater than total payment. and choose minimum date out of it.
let me know if require further help I will give you SQL query. But you should try by your own
Edit 1
this will provide you running_sum
_______Subquery1_______
select a.LoanNO,a.Scheduledate,a.Amount,sum(b.amount)run_sum from
Paymentschedule a
join PayamentSchedule b
on a.LoanNo=b.LoanNo and a.ScheduleDate>b.ScheduleDate and
a.ScheduleDate<=now() group by 1,2,3
total collection against loan
_______subquery 2_____
select LoanNo,sum(amount)total collection from collection group by 1
now
select a.LoanNo,min(ScheduleDate) overduestartdate from subquery1 join subquery2 on
a.LoanNO=b.LoanNO
and a.run_sum>b.Collection group by 1
modify according to your schema

Powerpivot sum from dimension table

I am a graduate intern at a big company and I'm having some trouble with creating a measure in PowerPivot.
I'm quite new with PowerPivot and I need some help. I am the first person to use PowerPivot in this office so I can't ask for help here.
I have a fact table that has basically all journal entries. See next table. All entries are done with a unique ID (serialnumber) for every product
ID DATE ACCOUNT# AMOUNT
110 2010-1-1 900 $1000
There is a dimension table with has all accounts allocated to a specific country and expense or revenue.
ACCOUNT# Expense Country
900 Revenue Germany
And another dimension table to split the dates.
The third dimension table contains product information, but also contains a column with a certain expense (Expense X).
ID Expense X ProductName Productcolour
110 $50 Flower Green
I made sure I made the correct relations between the tables of course. And slicing works in general.
To calculate the margin I need to deduct this expense x from the revenue. I already made a measure that shows total Revenue, that one was easy.
Now I need a measure to show the total for Expense X, related to productID. So I can slice in a pivot table on date and product name etc.
The problem is that I can't use RELATED function because the serial number is used multiple times in the fact table (journal entries can have the same serial number)
And if I use the SUM or CALCULATE function it won't slice properly.
So how can I calculate the total for expense X so it will slice properly?
Check the function RELATEDTABLE.
If you create a dummy dataset I can play around and send you a solution.

Run a query to check consistency in SQL Server

I need some help with a SQL query and logic in general. (Using MSSQL Server)
I need to check the consistency of payments at certain retailers over a period of three months.
So I've got a table with all my transactions and the following columns:
TransactionID , AccountNumber , Retailer, Date .... (few other irrelevant ones)
Now one Accountnumber could have many transaction IDs. (One account could decide to make several payments during one month).
I have 4 unique retailers' ids, let's call them (101,102,103,104)
Now for consistency I want to get the following data:
The count of transactions where there was only one payment per account for the month at each retailer.
So I'd have:
| # Payments For Month | Retailer | Number of Transactions
| 1 Payment | 101 | 5000
...
But I also want to see how many transactions there were from accounts that made payments at multiple retailers
So I'd want something like:
| 2 Payments | 102 & 104 | 20
Which would mean that an account made 20 payments at retailer 102 & 104.
I don't as much care about how many accounts, more the amount of transactions.
I also want it broken down by month, but I've decided to do a seperate query for each month.
I've imported the data into a local DB on my personal laptop so I could go crazy, so I'll be able to try any method.
The goal of this query is to check the consistency of payments by people (accounts) at certain retailers. How many transactions do they loyally make at one retailer every month, how many transactions are there where they've gone to two retailers? or three? or all four?

Best practice for keeping historical data in SQL (for SSAS Cube use)

I am working on an Hotel DB, and the booking table changes a lot since people book and cancel reservation all the time. Trying to find out the best way to convert the booking table to a fact table in SSAS. I want to be able to get the right statsics from it.
For example: if a client X booked a room on Sep 20th for Dec 20th and canceled the order on Oct 20th. If I run the cube on the month of September (run it in Nov) and I want to see how many rooms got booked in the month of Sep, the order X made should be counted in the sum.
However, if I run the cube for YTD calculation (run it in Nov), the order shouldn't be counted in the sum.
I was thinking about inserting the updates to the same fact table every night, and in addition to the booking number (unique key) and add revision column to the table. So going back to the example, let say client X booking number is 1234, the first time I enter it to the table will get revision 0, in Oct when I add the cancellation record, it will get revision 1 (of course with timestamp on the row).
Now, if I want to look on any piroed of time, I can take it by the timestamp and look at the MAX(revision).
Does it make sense? Any ideas?
NOTE: I gave the example of cancelling the order, but we want to track another statistics.
Another option I read about is partitioning the cubes, but do I partition the entire table. I want to be able to add changes every night. Will I need to partition the entire table every night? it's a huge table.
One way to handle this is to insert records in your fact table for bookings and cancellations. You don't need to look at the max(revision) - cubes are all about aggregation.
If your table looks like this:
booking number, date, rooms booked
You can enter data like this:
00001, 9/10, 1
00002, 9/12, 1
00001, 10/5, -1
Then your YTDs will always have information accurate as of whatever month you're looking at. Simply sum up the booked rooms.

Need ideas/advices about a database structure

Let's think we have 100+ hotels, and each hotel has at least more than 3 room types.
I want to hold hotel's capacity for one year in the past and one year in the future. How should i design the database for easiest use.
Example:
A hotel has 30 rooms. 10 x "Standard
room", 10 x "Duplex Room", 10 x "Delux
room" I will keep this example on
standard rooms. Today is: 13.01.2011 I
want to keep records from 13.01.2010
to 13.01.2012 What i will store in
database is available rooms. Something
like this(for standard room):
13.01.2011: 10
14.01.2011: 9 (means 1 standard room sold for this day)
15.01.2011: 8 (means 2 standard rooms sold for this day)
16.01.2011: 10 (all available for this day)
17.01.2011: 7 (means 3 standard rooms sold for this day)
18.01.2011: 10
etc...
Thanks in advance.
Let me try to summarize your question to see if I understand it properly:
You have a set of Hotels. Each Hotel
has a set of Rooms. Each Room belongs
to one of a number of possible Room
Types. The lowest level of detail
we're interested in here is a Room.
This suggests a table of Hotels, a lookup table of Room Types, and a table of Rooms: each Room will have a reference to its associated Hotel and Room Type.
For any given day, a room is either
booked (sold) or not booked (let's
leave off partial days for simplicity
at this point). For each day in the
year before and the year after the
current day, you wish to know how many
rooms of each type were available (non-booked) at
each hotel.
Now, since hotels need to be able to look at bookings individually, it's likely you would maintain a table of bookings. But these would typically be defined by a Room, a Start Date, and a number of Nights, which isn't ideal for your stated reporting purposes: it isn't broken down by day.
So you may wish to maintain a "Room Booking Log" table, which simply contains a record for each room booked on each day: this could be as simple as a datestamp column plus a Room ID.
This sort of schema would let you generate the output you're describing relatively easily via aggregate queries (displaying the sum of rooms booked per day, grouped by hotel and room type, for example). The model also seems like it would lend itself to an OLAP cube.
I did a homework question like this once. Basically you need at least 3 tables: one which holds the rooms, one which holds the reservations, and another table that links the too because its not a specific room that is reserved at a given time, its a specific type of room.