SQL: retrieve all rows that have a date between two dates - mysql

I'm making a small booking manager for my family's bed and breakfast.
I have a "booking" table that contains among other things a column called "arrivalDate" and a column called "departureDate".
I want to do a SELECT query where I retrieve all bookings that cover a certain date.
IE:
booking table:
name= John, arrivalDate= 01/01/2014, departureDate= 10/01/2014
name= Susie, arrivalDate= 04/01/2014, departureDate= 07/01/2014
I would like to do a query where it returns all bookings that are staying on 05/01/2014
In this case it would return both John's and Susie's booking.
Another query for 02/01/2014 would return only John's booking.
What would such an SQL query look like?
(NOTE: to not confuse anyone, the dates I put here are d/m/Y, I know that SQL uses Y/m/d, I can sort that myself, just looking for the logic)

select * from table where arrivalDate <= yourDate and yourDate <= departureDate
Replace yourDate with date which you need (for example 05/01/2014 according to DB format).

Related

SQL query : aggregating records having a timestamped field, where fields timestamp falls in same time unit (sec, min, hour..)

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

Mysql Function multiple entries in one cell

So I'm working on a schedule system for my job a basically i wanted to know if there is a way where mysql can do something like:
|Monday |tuesday|wendsday|total
|Dan |5am-7am |7am-6pm|6am-11am|
11am-2pm| |2pm-7pm |
5pm-12am|
where i can enter multiple shifts on 1 day for each person in the same cell if needed instead of the name repeating several times like:
Dan|5-4|
Dan|6-8|
and if there is a function to calculate total time in one cell with multiple shifts
There is a way (representing the data as string), but you wouldn't want to do this - you will loose all calculations, searches etc.
You should not try to represent the data in the database exactly as how it looks on paper.
I would make a table like this:
ShiftID|Person|StartTime|EndTime
Making StartTime & EndTime columns of type DATETIME, you will store not only the HH:mm of a shift's start, but also the day. This is helpful when you have a shift which starts on one day and ends in the next, like starting on Monday 2017-05-15 23:00 and ending on Tuesday 2017-05-16 02:00.
You can extract the date only from this filed using MySQL DATE() function and select only those entires which start OR end on this day.
To calculate the shift's duration you can use MySQL function TIMESTAMPDIFF()
You can even use DAYOFWEEK() to get if it is Monday, Tuesday, etc.
About duplicating the person's name - I would make another table, which will match users with their data to IDs an use ID in the column Person, but for a starter and if your data is not big and if speed is not an issue and if typo errors (like Den instead of Dan) are not a problem ... you could use the name directly in this table.
After storing the data in a table like this you could represent it as you wish in HTML (or print).
You can create a third table with the following columns:
person_id int,
start_time datetime,
end_time datetime
Where person_id would be foreign key to Person table and start_time and end_time would be datetime columns. You can then store multiple records for a person in this table and use MySQL's date functions with GROUP BY to generate the report similar to the one in question.

Which database method should I take to collect my monthly information

I have information to be collected monthly. same data columns but different content of course. I'm asking about which are the best way to make the user insert this data, should I make a database table for each month with the same columns, or should I make one table with one column to determine the month.
For example:
table: July
id|program_name|program_date|program_result
table: June
id|program_name|program_date|program_result
Or:
table: monthly_info
id|program_name|program_date|program_result|month
I'm asking which way is more efficient than the other.
Thank you
Create one table to save all your data with date.
table: monthly_info
id|program_name|program_date|program_result|date
Then you can query monthly data as below.
If your condition month parameter is integer. Use this query. (this will return all data matches to month August)
SELECT * FROM monthly_info WHERE MONTH(date) = 8
If your condition month parameter is string. Use this query.
SELECT * FROM monthly_info WHERE DATENAME(mm, date) = 'August'

Select leave data from attendance table given the following condition

I have attendance data for employees stored in the table attendance with the following column names:
emp_id (employee ID)
date
type (leave, absent, etc.)
(there are others but I'm omitting them for the sake of simplicity)
My objective is to retrieve all dates of the given month on which the employee was on leave (type = 'Leave') and the last leave taken in the last month, if any.
It's easy to do it using two queries (I'm using PHP to get process the data), but is there any way this can be done in a single query?
I'm answering my own question so as to close it. As #bpgergo pointed out in the comments, UNION will do the trick here.
SELECT * FROM table_name
WHERE type="Leave" AND
date <= (CURRENT_DATE() - 30)
Select the fields, etc you want then se a combined where clause using mysql's CURRENT_DATE() function. I subtracted 30 for 30 days in a month.
If date is a date column, this will return everyone who left 1 month or longer ago.
Edit:
If you want a specific date, change the 2nd month like this:
date <= (date_number - 30)

Number of rows returned when adding before/after date logically inconsistant

I have a database containing information about a students visit to our tutoring center. Each time a student visits a record is produced which includes their names, their student number the date they visited, what they were there for and how long they were there.
We create new tables for each term
I was asked to get an unduplicated count of how many students were there during a certain term so I run the following.
SELECT * FROM `tutoringdata_201350` group by `anum`
anum being the students unique identification number, which returns 524 results out of 5525 total records. In theory that should be my unduplicated count.
I was then asked to get records before and after a certain date in that same table, so I run.
SELECT * FROM `tutoringdata_201350` WHERE `cDate` <= "09/30/2013" group by `anum`
Which works, so far as the date is concerned and no duplicate people are returned so far as I can see in the results window if I sort by the anumber they are all unique. BUT the total number of results returned is 375
So to get students after that date I run
SELECT * FROM `tutoringdata_201350` WHERE `cDate` > "09/30/2013" group by `anum`
which also appears to work, no duplicated students in the returned results but total number of returned results is 428.
375 + 428 is 803 not 524 which I would expect. I'm having trouble following the logic, which of the 2 different types of queries are producing an inaccurate number of results.
You are misusing the pernicious nonstandard MySQL extension to GROUP BY. http://dev.mysql.com/doc/refman/5.6/en/group-by-handling.html
You probably want something like this;
SELECT COUNT(DISTINCT anum) unique_students
FROM `tutoringdata_201350`
WHERE cDate <= 'whatever'
You could also do this to find out how many visits each student made.
SELECT COUNT(*) visits,
anum
FROM `tutoringdata_201350`
WHERE cDate <= 'whatever'
GROUP BY anum
You are also, I think, making a mistake in the way you are comparing dates.
MySQL uses an internal DATE and DATETIME format. If you want to compare such data items in your table to a text-string constant, you need to use the correct format -- YYYY-MM-DD -- for that string. For example:
WHERE cDate <= '2013-09-30'
The comparison in your example isn't correct. Edit. If your dates are stored as text strings as MM/DD/YYYY, you need to use the following sort of comparison.
WHERE STR_TO_DATE(cDate, '%m/%d/%Y') <= '2013-09-30'
This will convert your legacy date strings to DATE format. Then the comparison will work. If you don't do this MySQL is just comparing strings to strings. (You may, or may not, luck out if the years don't vary.)
Now, your counts of unique students before and after the first of October do not necessarily sum up to the count of unique students for the whole term. Here's an example.
Joe Sept 28
Joe Sept 29
Mary Sept 30
Henry Sept 30
Joe Oct 1
Stephen Oct 1
Overall there are four distinct students. In Sept there are three. In October there are two. If you add those two numbers you get five. That's more because you're double-counting Joe by adding those two numbers.