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=??
Related
I need to store birthdates, but for some people I only know the year and not the month and day. For month/day I will only allow either null or both of them filled out. How should I structure my database?
Currently I have this:
birth_year (YEAR)
birth_month (INT)
birth_day (INT)
Where birth_month and birth_day are nullable, but is it better to go for something like:
birth_date (DATE)
has_month_and_day (TINYINT/BOOL)
And set month and day to "01-01" if has_month_and_day is false?
Or this:
birth_year (YEAR)
bith_date (DATE)
And go for bith_date with the full date if everything is filled out and birth_year if birth_date is null?
Other suggestions? I still need to be able to tell if month and day was filled out so I can't just use one date column and set month and date to "01-01".
I will also need to filter by year and sort by date if that matters for the decision.
Thanks!
Edit // I found this in the MySQL docs. What do you think?
MySQL permits you to store dates where the day or month and day are
zero in a DATE or DATETIME column. This is useful for applications
that need to store birthdates for which you may not know the exact
date. In this case, you simply store the date as '2009-00-00' or
'2009-01-00'.
I would store them separately. You can always query on them as a full date using CONCAT and CAST 'mystring' as date if needed.
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.
I have a week column with week numbers as w0, w1, w2.... I am trying to get last last six weeks data. Here's the sql query I am using.
SELECT * FROM week
WHERE uid = '9df984da-4318-1035-9589-493e89385fad'
AND report_week BETWEEN `'w52' AND 'w5'`;
'w52' is essentially week 52 in December 2015 and 'w5' is Jan 2016. The 'between' seems to not work. Whats the best way to get data from the above two weeks?
Here's the CREATE TABLE statement:
CREATE TABLE `week` (`uid` VARCHAR(255) DEFAULT '' NOT NULL,
`report_week` VARCHAR(7) NOT NULL,
`report_files_active` BIGINT DEFAULT NULL);
Essentially this table is getting populated from other table which has date column. It uses dates from other table and summarizes weekly data into this.
Any help is appreciated.
Refer to this SO Discussion which details the reasons for a problem similar to yours.
BETWEEN 'a' and 'b' actually matches to columnValue >='a' and columnValue <= 'b'
In your case w52 is greater than w5 due to lexicographic ordering of Strings - this means that the BETWEEN clause will never return a true (think about it as equivalent to saying BETWEEN 10 and 1 instead of BETWEEN 1 and 10.
Edit to my response:
Refrain from storing the week value as a string. Instead here are a couple of approaches in order of their preference:
Have a timestamp column. You can easily then use MySQL query
facilities to extract the week information out of this. For a
reference see this post.
Maintain two columns - YEAR, WEEKNO where YEAR will store values
like 2015, 2016 etc and WEEKNO will store the week number.
This way you can query data for any week in any year.
please show me table structure and DB name because it different for other, if it is any timestamp then we can use BETWEEN 'systemdate' AND 'systemdate-6'
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
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