How to create a double graphic using two tables in Tableau - mysql

I am working with Tableau in order to obtain a report for my company. The report is a sales based one that should include both booking total amount and total number of booking that have been sold.
So, as an example, we have 2 tables right now:
Bookings.
ID -- primary key, unique.
date -- date of booking creation
Payment.
ID -- primary key, payment id. Unique
bookingId -- FK. booking Id. Can be repeated.
Amount -- Amount paid.
Date. -- Date of payment. We can pay a booking in different dates. We can refund (so every time we refund we will have one line for this payment in negative).
What we need:
We would like to display a graphic report with both data. Price & number of bookings filtering by both dates.
We tried to do that using countD and filtering by date from payment table but we get different number of bookings because we can have 1-N payments of 1 booking.
If we filter by booking date, we won't have the same values so it should be nice to combine both filters.
I don't know the viability of this...

Related

Adaptive SELECT statement dependent certain values being present

I am trying to build a SELECT statement on a MySQL view that will end up as a resource on a calendar app. Clients are booking out a piece of equipment for a period of time (bookings). Payment (payments) is taken at the beginning of the hire period for the equipment but further payments can be made if the hire period is extended. Therefore a single booking will have one, possibly many payments associated with it. Payments are recorded with the amount paid and the date they are paid.
Bookings for equipment must appear on the calendar if the date being viewed is within the hire period. Also, and this is the part I am having trouble with, payments, if they have been made on the date viewed, must be displayed (the reason for this is that my customer wants a daily total of takings for hires). If they haven't made a payment on the date viewed then the amount must appear as 0.
My view is built from three tables - bookings, payments and clients. The clients table is unimportant in this problem as it is just used in the view to generate the client name to be displayed on the calendar.
[![bookings][1]][1]
[![payments][2]][2]
The view is shown below
[![view_bookings_detail][3]][3]
This is what I am attempting to achieve. When the user opens the calendar or changes the calendar date, that date is used in my resource SELECT query as a parameter. In the first example we are viewing 04/07/2022. The parameter [selected_date] is set to '2022-07-04'. My initial SELECT statement was -
SELECT client_id, title, longterm_fee FROM view_bookings_detail WHERE start_date <= '[selected_date]' AND end_date >= '[selected_date]'
This returns -
[![calendar resource feed][4]][4]
Clearly this is no good as it would result in multiple entries for both hirer's. If I amend the select statement to -
SELECT client_id, title, longterm_fee FROM view_bookings_detail WHERE start_date <= '[selected_date]' AND end_date >= '[selected_date]' AND ltf_paid_on = '[selected_date]'
This returns -
[![amended calendar resource feed][5]][5]
This returns what I want but only because the two hirer's made payments on 04/07/2022.
If I were to view 05/07/2022, for instance, using the above logic, no records would be selected as no payments were made on 05/07/2022. What I would need returned in this case is a single record for each hirer with the longterm_fee showing as 0
I don't know how to achieve this. Anyone any ideas please?

How to calculate a sum of entries (balance) efficiently in SQL?

We have a table "bookings":
id int
amount float
user_id
A users "balance" is the sum of all bookings. After years and some users with 100k+ entries that calculation is getting slow.
I have 2 solutions in mind:
Create a "balance" column in "users" table and add or substruct amounts each time a booking is added
Create a "last_balance" column in "users" table that is updated once a year with the users balance on the 01.01. 00:00:00, then balance is "last_balance" + sum(all-bookings-since-01.01.)
The issue with 1) is that any bug or delay in the db might result in a wrong balance. Therefore I think the balance should rather be the sum of bookings than an individual number.
Is there a "right" way to calculate a users balance in any system where users hold money?

Unify records in one row

I have 2 tables in my DB
Table1 has
sales_ID
date
calls_volume
Table 2 has
sales_ID
date
sales_volume
skills_volume (the skills where the sales was logged in)
What makes things harder, is that in Table 1, there's one record per sales and date (in other words, every sales has 1 record in every day).
However table2 has one record per sales, date and skills.
When I join the two tables in a query (date and sales_id) I get the calls volume multiplied by skills volume).
can any one help me on that?

Trying to think of the best database schema for storing dates ranges that will require joins

(Table names in quotes)
Let's say there are "users" that try to sells "products". They earn a commission on all "product_sales" (id, product_id, user_id, total, sale_date). I want to somehow store their commission rate based on certain dates. For example, a user will earn 1% from 2015-01-01 to 2015-01-15, 2% from 2015-01-16 to 2015-01-28, and 3% from 2015-01-29 onwards.
I want to run a query that calculates the total commissions for a user in January.
I want to run a query that calculates daily earnings in January.
How do I store the commission rates? One idea was having a table "user_commissions" that has (id, user_id, commission_rate, from_date, to_date). It would be easy to calculate the rate for (1) if commissions stayed the same, in which case I'd do this:
SELECT (sum(total) * 0.01) as total_commissions FROM product_sales WHERE user_id = 5 and sale_date between '2015-01-01' and '2015-01-31'
But with commission rates variable this is more complex. I need to somehow join the commissions table on each sale to get the right totals.
Another question would be:
How do I store the users' current commission rate that doesn't have an expiration date and include that in the reports? In my example, "3% from 2015-01-29 onwards". This has no end date.
Your table structure is a very reasonable structure and often used for slowly changing dimensions. Storing the effective and end dates in the structure is important for efficiency.
One way to store to_date for the most recent commission is to use NULL. This allows you to do:
select *
from commissions
where to_date is null
to get the most recent record.
However, a better way is to use some far distant date, such as '9999-12-12'. This allows you get the most recent commission using:
where curdate() between from_date and to_date
This is an expression that can also make use of an index on from_date, to_date.
Honestly, I would store user commission percentages and the effective dates of those commissions in one table.
TABLE: COMMISSION
user_id, date_effective, commission
In the other table I would store sales data. With each sale, I would keep the commission the salesperson got on the sale. (Added bonus, you can change the commission on any sale, like an override of sorts.)
TABLE: SALE
sale_id, sale_date, user_id, sale_amount, commission
When you create the row in your program, you can grab the correct commission rate using the following query:
SELECT commission from commission WHERE user_id=[user's id] AND date_effective<=[sale date, today] ORDER BY date_effective ASC;
MySQL Left Joins, and SQL in general, can get really tricky when trying to join on dates that don't exactly match up. (Looking back, basically.) I am struggling with the same problem right now without the luxury of the solution I just suggested.
(This whole post is based on the assumption that you aren't going to be directly interacting with this database through a DBMS but instead through an application.)

Access: Auto-Fill in values in a table based on certain criteria. (Payment schedule)

I basically want to create a payment schedule in a separate table based on 4 values that a user would select. The payment schedule is very basic and the table only needs 2 columns, 1) Date of payment, 2) payment amount.
The 4 criteria values that are used to fill out this simple table would be: 1) the total amount of money, 2) number of payments, 3) the frequency of the payments (monthly, quarterly, semi-annually, annually), 4) the date of the first payment.
The way that I envision this is having a Form where these 4 values will be selected. On that form there can be a button to execute the command to fill in a datasheet with the appropriate values.
The first entry would obviously be on the date of the first payment, and the amount for that entry would be the total amount divided by the number of payments. For the second record dollar amount would be the same and the date would be the first payment date + the frequency. So if the first payment date is 1/1/2000 and the frequency annually, then the second entry date would be 1/1/2001. Etc.. until the last payment is made.
While it is a pretty simple payment schedule, I'm not sure how to best approach this in Access and if it's even possible. Would appreciate some input and direction. Thank you!
You will need
-- A numbers table with integers from 0 to the highest number of payments possible, indexed on the number.
-- A combobox called Frequency on forms payments with the following properties:
Row source: q;quarter;m;month;ww;week
Row source type : value list
Bound column : 1
Column count : 2
Column widths : 0, 1
-- A query
INSERT INTO Payments ( UserID, PaymentDate, Payment )
SELECT [Forms]![Payments]![UserID],
DateAdd([Forms]![Payments]![Frequency],
[Number],
[Forms]![Payments]![Startdate]) AS Expr2,
[Forms]![Payments]![LoanAmount]/
[Forms]![Payments]![NumberOfPayments] AS Expr3
FROM Numbers
WHERE (((Numbers.Number)<[Forms]![Payments]![NumberOfPayments]));
-- A button to run the query.