Unify records in one row - mysql

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?

Related

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?

How to create a double graphic using two tables in Tableau

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...

Breaking Up a Date Range by Individual Dates

I have a table with the following features: Invoice ID, billing_period_start, billing_period_end, and items_purchased during that period.
I'm looking to break out a date range by individual dates. A date range can be contained within one month, but it can also be spread across two months, unequally. This will effectively create many more records than are currently in the table. Once I have done that, I need to breakout the amount of purchased items equally among that dates of the daterange.
billing_period_start billing_period_end
-------------------- ------------------
2010-03-05 2010-03-07
2010-04-29 2010-05-05
2010-06-29 2006-08-12
billing_date
------------
2010-03-05
2010-03-06
2010-03-07
2010-04-29
2010-04-30
2010-05-01
...
2010-05-05
2010-06-29
2010-06-30
...
2010-08-12
Now that the date range is broken into individual dates, I need to take the items_purchase and divide it by the number of the days in the billing period for each date, so that I have the items_purchase_per_date.
select
invoice_line_id AS invoice_id
,items_purchased
,billing_period_start
,billing_period_end
,date_from_parts(YEAR(billing_period_start), MONTH(billing_period_start), 1) AS period1_month_start
,last_day(month_start, month) AS period1_month_end
,datediff(day, billing_period_start, billing_period_end) + 1 AS billing_period_length
from "INVOICE_DATA"
order by 1;
I'm running this on Snowflake, but can easily convert from mySQL, if someone knows that DBMS better.
The best way to handle this in a data warehouse is using a date dimension table. That is, a table that contains all the dates you need for analysis, plus any date attributes that are interesting as well, such as which week/month/quarter etc the date belongs to and so on.
Once you have table with unique rows for all relevant dates, you can more easily tackle date spine challenges like this.
For example, for your case you'd write (assuming dates is the name of your date dimension and calendar_date the name of the column containing the unique dates:
select
d.calendar_date,
i.*
from
dates d
join
invoice_data i
on d.calendar_date between i.billing_period_start and i.billing_period_end
Now you have one row per date between those start/end dates and you can do your daily billing allocation.

datediff() query for multiple dates

I have a table named orders that contains order_id, order_date and order_shipped. I need to be able to query the difference in days between ordered and shipped for the whole table but only display the order_id's that have 15 or more days between them and I have no idea how to build that query.
Basically you want to select the ids where the date difference is at least 15.
SELECT order_id
FROM orders
WHERE datediff(order_shipped, order_date) >= 15
This could be slow if there are many orders, because the function result cannot be indexed and needs to be calculated every time.

How to deal with counting items by date in MySQL when the count for a given date increment is 0?

I'm looking to make some bar graphs to count item sales by day, month, and year. The problem that I'm encountering is that my simple MySQL queries only return counts where there are values to count. It doesn't magically fill in dates where dates don't exist and item sales=0. This is causing me problems when trying to populate a table, for example, because all weeks in a given year aren't represented, only the weeks where items were sold are represented.
My tables and fields are as follows:
items table: account_id and item_id
// table keeping track of owners' items
items_purchased table: purchaser_account_id, item_id, purchase_date
// table keeping track of purchases by other users
calendar table: datefield
//table with all the dates incremented every day for many years
here's the 1st query I was referring to above:
SELECT COUNT(*) as item_sales, DATE(purchase_date) as date
FROM items_purchased join items on items_purchased.item_id=items.item_id
where items.account_id=125
GROUP BY DATE(purchase_date)
I've read that I should join a calendar table with the tables where the counting takes place. I've done that but now I can't get the first query to play nice this 2nd query because the join in the first query eliminates dates from the query result where item sales are 0.
here's the 2nd query which needs to be merged with the 1st query somehow to produce the results i'm looking for:
SELECT calendar.datefield AS date, IFNULL(SUM(purchaseyesno),0) AS item_sales
FROM items_purchased join items on items_purchased.item_id=items.item_id
RIGHT JOIN calendar ON (DATE(items_purchased.purchase_date) = calendar.datefield)
WHERE (calendar.datefield BETWEEN (SELECT MIN(DATE(purchase_date))
FROM items_purchased) AND (SELECT MAX(DATE(purchase_date)) FROM items_purchased))
GROUP BY date
// this lists the sales/day
// to make it per week, change the group by to this: GROUP BY week(date)
The failure of this 2nd query is that it doesn't count item_sales by account_id (the person trying to sell the item to the purchaser_account_id users). The 1st query does but it doesn't have all dates where the item sales=0. So yeah, frustrating.
Here's how I'd like the resulting data to look (NOTE: these are what account_id=125 has sold, other people many have different numbers during this time frame):
2012-01-01 1
2012-01-08 1
2012-01-15 0
2012-01-22 2
2012-01-29 0
Here's what the 1st query current looks like:
2012-01-01 1
2012-01-08 1
2012-01-22 2
If someone could provide some advice on this I would be hugely grateful.
I'm not quite sure about the problem you're getting as I don't know the actual tables and data they contain that generates those results (that would help a lot!). However, let's try something. Use this condition:
where (items.account_id = 125 or items.account_id is null) and (other-conditions)
Your first query is perfectly acceptable. The fact is you don't have data in the mysql table and therefore it can't group any data together. This is fine. You can account for this in your code so that if the date does not exist, then obviously there's no data to graph. You can better account for this by ordering the date value so you can loop through it accordingly and look for missed days.
Also, to avoid doing the DATE() function, you can change the GROUP BY to GROUP BY date (because you have in your fields selected DATE(pruchase_date) as date)