How to create calculation in MySQL between date and price - mysql

I'm want to calculate the date to count days and calculate with price or custom price in MySQL.
This is booking table
CREATE TABLE tbl_booking(
booking_id int(11) NOT NULL AUTO_INCREMENT,
user_id int(11),
comp_id int(11),
register_number varchar(100),
booking_status int(11),
pick_date date,
drop_date date,)
This is vehicle table
CREATE TABLE tbl_vehicle(
register_number varchar(100) NOT null,
vehicle_model varchar(255),
vehicle_type varchar(255),
vehicle_price varchar(10));
So, like this:
totalprice = (pick_date - drop_date) * vehicle_price

Join two tables on common column which seems to be register_number then use datediff to calculate the difference in days between two dates and multiply it by price to get total price for each booking:
select
b.*,
datediff(b.drop_date, b.pick_date) * v.price as total_price
from tbl_booking b
inner join tbl_vehicle v on
b.register_number = v.register_number
Remember that you should substract later date from an earlier one (drop - pick) instead of (pick - drop) since this will give you a negative number.

Use below :
DATEDIFF(pick_date , drop_date) * price
DATEDIFF will give you day different between two dates.
SELECT DATEDIFF("2017-06-25", "2017-06-15");
Output will be : 10
As you price is in another table hope you will be able to join and calculate.

You can convert the date field data into days, then subtract them, and multiply with price. Please note that the syntax can vary among the different implementations of SQL. With the correct MySQL syntax this would be:
SELECT (TO_DAYS(drop_date) - TO_DAYS(pick_date)) * price FROM tbl_booking;
Also note that according to your code, tbl_booking does not contain the price field, so you'll probably need to join with another table as well.

Related

My SQL Query - Get items that had there prices reduced in the last 30 days

I have a table that keeps track of inventory price updates.
CREATE TABLE pricechangelog (
id int,
SKU varchar(50),
oldSelling DOUBLE(22,2),
newSelling DOUBLE(22,2),
date DATETIME
);
I would like to get the items that had their price reduced overrall in the last 30 days,
how would I go about doing that
This could be possible by find the difference of the current timestamp and the date. DATEDIFF() Function, and the newselling value shuould be less than the oldselling
SELECT *
FROM pricechangelog
WHERE DATEDIFF(CURRENT_TIMESTAMP, date)<= 30
AND oldSelling>newSelling;

How can I store price of something for every day of the year in database?

I am working on a project but a have a problem with designing of database.
I need to store the price of something for every day in the year but i need to be able to change the prices for specific day.
Do i need to create a column for every day, in this approach i must create 365 columns in the table.
Do you have any better solution to this problem, any help will be appreciated, thank you.
You should create a table with 6 columns.
CREATE TABLE IF NOT EXISTS priceHistory (
`price` decimal(8,2) NOT NULL,
`date` datetime,
`productId` VARCHAR(50),
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`createdAt` TIMESTAMP DEFAULT NOW(),
`updatedAt` TIMESTAMP
) ENGINE = INNODB;
Now you can insert the date and price for every day, the columns created_at, updatedAt and id are automatically inserted (and updatedAt automatically updated), so you don't need to bother for them any more.
If you are saving those prices on a daily base and access the data later, you don't even need the date column, just use createdAt which, again, is automatically created on INSERT.
Once you have data, you can query for it like
SELECT * FROM priceHistory WHERE DATE(`date`) = '2015-02-29';
You might also find mysql's documentation on DATE functions usefull.
Edit
As #murenik mentioned in his answer, the recomended way would be to create a relation to the table holding your product details, which you might have. To do this, change the productId statement to
productId INT PRIMARY KEY REFERENCES products(id),
This will link those tables, making future queries easier and more effective.
SELECT ph.*, p.*
FROM products p
INNER JOIN priceHistory ph on p.id = ph.productId
See mysql JOIN.
The classic solution would be to use a junction table, with a price per product per date:
CREATE TABLE product_prices (
product_id INT REFERENCES products(id),
price DECIMAL (5, 2),
date DATE,
PRIMARY KEY (product_id, date)
);
We had a complex rate table at one place I worked, and instead of storing the rate for each day, we stored the rate on the first day it changed. So if Unit1 (of a motel for example) was $50 a night from January to April, then $65 a night over the summer during tourist season, then back to $50 a night in the fall, the rate table would have 3 records:
Start Date Close Date Unit # Rate
------------ ----------------- ------- -------
January 1, 2015 March 30, 2015 Unit1 $50
April 1, 2015 September 30, 2015 Unit1 $65
October 1, 2015 December 21, 2015 Unit1 $50
Then all you would need to do is find a rate record where your chosen date falls between the start and end date.
just make a table for
id of the product | date | price

Hotel Monthly bookings grouped by Hotel ID and Hotel name

I need help with a MySQL String that I can use every month to generate a tabular monthly report for my online booking system showing report title as "Total Hotel Bookings for yyyy-mm-dd, and having the Hotel ID sequentially in the first column (starting with 1000, 1001,etc increments by 1), Hotel name in the second column, City in column 3, State in column 4, e-mail address in column 5, and total umber of bookings for the month in column 6.
In my MySQL database I have a table called sales and it has the following database structure for the key variables:
FIELDS TYPE Notes
hotelid VARCHAR(5) Property ID (these are all digits)
hotelname VARCHAR(35) Property name
booked DATE Date booked in yyyy-mm-dd format
ref VARCHAR(16) Booking reference (alphanumeric e.g. Booking12345)
numitems TINYINT(4) Number of items
itemno Item number
city VARCHAR(40)
state VARCHAR(40)
email VARCHAR(70)
The string I have is not appropriate for my requirements is given below:
“SELECT SUM(??), SUM(??) FROM sales WHERE arrdate>=’??’ AND depdate>=’??’ AND propid=??” We would replace ?? with the fields or data which would depend on what we wanted to retrieve.
Please help me with a String that can be used immediately I get it.
Thanks. Velox
You have several options:
using between in your query, i.e. WHERE columname BETWEEN '2014-07-04 00:00:00' AND NOW()
using an unsigned int instead of a date and therefore timestamps, i.e. WHERE columname BETWEEN '".$yourNumericTimestamp."' AND '".time()."' (php)
I usually use timestamps since they give me less headache with formatting.
Note that if you're not 110% sure that $yourNumericTimestamp is numeric you have to wrap it with $db->real_escape_string($yourNumericTimestamp).
EDIT: Too match your example query:
SELECT SUM(??), SUM(??) FROM sales WHERE arrdate BETWEEN ’??’ AND NOW() AND depdate BETWEEN ’??’ AND NOW() AND propid=??

How to retrieve data from database table with condition in between date?

I need to check the available hotels and quantity of rooms available on the hotels for some duration(start_date and end_date.
I have a table test(id, date, qty, hotel_id). I need to access all the the hotel ids with some condition on qty (eg. qty>2) and date between two dates(for eg: the date field of the test table should have date value greater than the '2013-05-06' and end date less than '2013-05-10').
I tried this query:
select hotel_id
from test
where qty>2
and date between '2013-05-06' and '2013-05-10';
But, another condition is there must be all date between given dates. i.e. the date field should have all date date values: '2013-05-06', '2013-05-07', '2013-05-08', '2013-05-09', '2013-05-10' . If any of the above date is missing, then it should return empty resultset. And if all date are available with qty>2(let), then it should return list of hotel_ids.
How can it be done in a single MySQL query?
Try
SELECT `hotel_id`
FROM test
WHERE `date` BETWEEN '2013-05-06' AND '2013-05-10'
AND `qty` >= 2
GROUP BY `hotel_id`
HAVING COUNT(*) = (DATEDIFF('2013-05-10', '2013-05-06') + 1)
SQLFiddle

With MySQL, how can I calculate a view field basing on a semi-related record?

I'm sorry for the vague title, but what I want to do can hardly be described with a one-liner.
I have a simple web app with a MySQL 5.1.30 backend to help me manage my finances. It's got a bill table:
id INT PRIMARY KEY,
date DATE
And a bill_rows table:
id INT,
bill INT REFERENCES bills (ID),
cost DECIMAL(16,2),
taxable TINYINT(1)
And finally, a taxed_bill_rows view, where an additional taxes column is introduced:
SELECT
r.id AS `id`,
r.bill AS `bill`,
r.cost AS `cost`,
(CASE
WHEN i.taxable
THEN floor((r.cost * 1.05 * 1.075) * 100) / 100.00 - r.cost)
ELSE
0.00
END) AS `taxes`
FROM bill_rows r
The 1.05 factor is the federal tax rate, and the 1.075 is the provincial tax rate. (The * 1.05 * 1.075 is not a mistake: the provincial tax is applied over the federal tax too.)
However, these values aren't up-to-date anymore (I'm actually very late on this). Since January 1st of this year, the federal tax rate is 1% higher, up to 1.085.
To solve the tax rate changes problem, I've created a new tax_rates table:
ID INT,
date DATE,
federal DECIMAL(4,2),
provincial DECIMAL(4,2)
Each time the tax rates change, I will insert a new record there.
Now, the problem is, how can I access the relevant tax rates, based on the date field of a bill, from my view? I can't just do LEFT JOIN tax_rates tr ON tr.date < b.date as that can potentially bring back too many records. Adding a tax_rates foreign key to the bills table would do it, but the changes are so occasional that it seems barely worth it.
Your tax_rates table needs two date columns to indicate the start & end:
CREATE TABLE tax_rates (
id INT,
start_date DATE,
end_date DATE,
federal_tax_rate DECIMAL(4,2),
provincial_tax_rate DECIMAL(4,2))
Then, you can use BETWEEN to JOIN:
JOIN tax_rates tr ON tr.date BETWEEN b.start_date AND b.end_date
foregn key for tax rate will be the best solution.
best for performance and best for maintenance,
any other solution will be slower and less readable
i.e you can add fields start_date and end_date to tax_rates table
and to do join like
left join tax_rates tr on b.`date` between tr.start_date and tr.end_date
in this case you also should keep 0 at start_date for first record and large date for last record