I have a table with exchange rates by date and a second table with customers sales.
TableA:
date of excahnge_rate
from_currency
to_currency
TableB:
customerid
total_bought
user_currency
date_bought
I need to get a table with the total_bought transformed into the same currency, so I need to check the exchange_rate on each date_bought and apply the rate on that date.
I would get the same TableB but with the total_bought in the same currency for all the records.
I'm an unexperienced user of SQL and I'm having troubles with this.
Related
I have a database table customers that records among others the arrival time of clients for a one month data. So, the customers table contains among other a column named arrival_time . (e.g., arrival_time = 12/1/2020 12:01:39 AM, arrival_time = 12/1/2020 12:01:34 AM etc…)
Is it possible to design/write an SQL query that returns the numbers of customers that arrived each second (or say, min, hour...) in this this one month data.
Thank you.
If you are using PostgreSQL you can use DATE_TRUNC(). For example:
select
date_trunc('minute', arrival_time) as at,
count(distinct customer_id) as cnt
from t
group by date_trunc('minute', arrival_time)
You can change 'minute' for 'day', 'week', 'second', etc. See https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC
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...
(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.)
I am trying to get a list of customers, films, and the number of days their rental was overdue (if that rental was kept longer than the rental duration).
For some reason, I am getting NULL for the number of days the rental was overdue using this query.
I got the tables from this resource:
http://dev.mysql.com/doc/sakila/en/sakila-structure-tables.html
Here is my query:
SELECT first_name, last_name, title, DATEDIFF(DATEDIFF(return_date,rental_date), rental_duration)
FROM sakila_customer
JOIN sakila_rental USING (customer_id)
JOIN sakila_inventory USING (inventory_id)
JOIN sakila_film USING (film_id)
WHERE sakila_film.rental_duration < DATEDIFF(sakila_rental.return_date,sakila_rental.rental_date);
The reason it's returning null is because you're using DATEDIFF on values that are note dates.
Look at this line right here:
DATEDIFF(DATEDIFF(return_date, rental_date), rental_duration)
When you execute the inside (the difference between return and rental date) you will have an integer. rental_duration is also an integer, so when you try to do a datediff between them you get null, because you aren't taking the difference of dates.
So what you should do is get the datediff of return and rental date, and then subtract the rental duration from that. That number will give you the number of dates overdue.
Try this:
SELECT first_name, last_name, title, (DATEDIFF(return_date, rental_date) - rental_duration) AS daysOverdue
FROM customer
JOIN rental USING (customer_id)
JOIN inventory USING (inventory_id)
JOIN film USING (film_id)
WHERE rental_duration < DATEDIFF(return_date, rental_date);
I downloaded the database from your link and ran this in the MySQL workbench and achieved this result set:
You will get a null if any of the values used to calculate the result are null.
Also, your expression doesn't look right, try:
Select ...
datediff(return_date, rental_date) - rental_duration overdue
from ...
...
where datediff(return_date, rental_date) - rental_duration > 0
I have a transaction table and I'm looking to generate a dataset to drive a line chart that shows the sum of all the sales happened on each day during a given period. I have never grouped results like that before and am scratching my head.
Let's say the table is called "transactions", the "datetime" field is called timestamp, and the sales amount on each transaction is "txn_amount". I want the result set to include each day: "1/2/10" and the sum of the transaction amounts.
I need to get a book and spend a week learning mysql... Thanks for helping me out.
select sum(txn_amount) ,timestamp from transactions where timestamp in (select distinct timestamp from transactions) group by timestamp
if datatype is datetime,Use this
select sum(amt) ,substring(dt,1,10) from transactions where substring(dt,1,10) in (select distinct substring(dt,1,10) from transactions) group by substring(dt,1,10)