I have a table which look like this:
Date | Day | Ingredients
-------------------------------------------
2014-08-20 | Wednesday | Salt
2014-08-21 | Thursday | Sugar
2014-08-22 | Friday | Salt&Sugar
2014-08-28 | Thursday | Salt
And I want to have only the dates there are in one week. Should I make an extra column 'Week' with the number of the week or is there a solution where I can set the beginning and the end of a week to only have the actual week. So I have all rows from the actual week.
SELECT * FROM table WHERE *`Date is in the actual week`*
You mean to get the data of current week?
Use the YEARWEEK function.
SELECT * FROM your_table
WHERE YEARWEEK(`date`, 1) = YEARWEEK(CURRENT_DATE, 1)
Update:
Use mode 1 if the beginning of week is Monday.
Related
I am working on a booking system where users can book certain services online. I am stuck on finding and displaying available time slots within a specific day. I know the length of the needed time slot is 1 hour and the business hours.
Is there a way to show time slots that has not yet been booked on a certain day and display only the available time slots that is available to be booked in a dropdown select form?
If a customer selects a specific day and clicks "Select Day" then it needs to query the DB and return the results.
My SQL structure is as follows
|id | title | start_time | end_time | booking_date |
| 1 | Name1 | 2022-05-12 08:00:00 | 2022-05-12 09:00:00 | 2022-05-12 |
| 2 | Name2 | 2022-05-12 10:00:00 | 2022-05-12 11:00:00 | 2022-05-12 |
| 3 | Name3 | 2022-05-12 13:00:00 | 2022-05-12 14:00:00 | 2022-05-12 |
| 4 | Name4 | 2022-05-12 14:00:00 | 2022-05-12 15:00:00 | 2022-05-12 |
as per above the select form should display the timeslots that is not already taken.
09:00 - 10:00
12:00 - 13:00
15:00 - 16:00
It would be something like:
select
id, title
from
<table>
where
start_time between '2022-05-12 00:00:00' and '2022-05-12 11:59:59'
and
booking_date is null
I don't know the name of your table, so you would need to replace <table> with that. I'm also assuming that "booking_date" will have a value to indicate that time slot has been reserved, that it's a date field, and it will be null if that slot hasn't been selected. However, booking_date could have a different purpose.
This is a lazy answer
(because I think just use SQL will do it, use subSelect and other function, but I don't know how to do, sorry.)
get today occupy time:
SELECT id, TIME(start_time) AS s_time FROM tablename
WHERE start_time >= '2022-05-12 00:00:00'
AND start_time < '2022-05-13 00:00:00'
diff time in php:
$sqlResult = []; // sql result
$timeAll = [
'00:00:00',
'01:00:00',
'02:00:00',
'03:00:00',
... // TODO: we need fill it
'23:00:00',
];
foreach ($sqlResult as $item) {
if (isset($timeAll[$item['s_time']])) {
unset($timeAll[$item['s_time']]);
}
}
return $timeAll;
// TODO: javascript or other client code can use it.
ref knowledge link:
MySQL SELECT WHERE datetime matches day (and not necessarily time)
If you choose 2022-05-26, and Peter is occupying room F25 from 2022-05-16 until 2022-05-29, it means the date you select must be out of this range.
So, the query below will only return rooms that were not booked on that day.
SELECT b.id, b.room_id as available_room FROM booking as b
WHERE(
unix_timestamp('$mydate')
NOT BETWEEN unix_timestamp(b.start_date)
AND unix_timestamp(b.end_time)
)
AND unix_timestamp(b.end_time) < unix_timestamp('$mydate');
Assuming $mydate is the variable that contains the date selected by the user, the above query will return rooms that will be available in the future on that particular day.
I have seen so many questions similar to this, but they all seem to be tailored to highlighting when date ranges are overlapping, I need the opposite.
Lets say I have a table like so
id| start_date | end_date | room_id
1 | 15/05/2018 | 30/06/2020 | 1
2 | 01/11/2018 | 31/10/2019 | 2
3 | 01/08/2020 | 31/07/2022 | 1
4 | 01/12/2019 | 30/11/2021 | 2
5 | 01/08/2020 | 31/07/2022 | 3
As you can see there are multiple bookings for each room. I need to be able to specify either a single start/end date or both, and get back what DOESN'T overlap (i.e, the available rooms)
For example, if i specified just a start date of 01/05/2018 then every room will return, or if i specify just an end date of 30/07/2020 then every room will return because neither of those dates are between the start and end date of each booking. Even though id 1 has a booking that ends on 30/06/2020 and a new one that starts on 01/08/2020, it would still be available because someone could book between those 2 dates.
If I specified both start and end dates, it searches through and returns only the rooms that have no bookings between the 2 dates at all.
I have read plenty of questions online and the logic seems to be
SELECT *
FROM bookings
WHERE $start_date < expiry_date AND $end_date > start_date
which i understand, but if I ran this query above with the following dates
SELECT *
FROM bookings
WHERE '2018-10-01' < expiry_date AND '2019-10-01' > start_date
it returns
id| start_date | end_date | room_id
1 | 15/05/2018 | 30/06/2020 | 1
2 | 01/11/2018 | 31/10/2019 | 2
How do I get it so that when I pass either a start date, end date or BOTH it returns the rooms that are available?
By De Morgan's Laws, we can negate the overlapping range query you gave as follows:
SELECT *
FROM bookings
WHERE $start_date >= expiry_date OR $end_date <= start_date;
The expression ~(P ^ Q) is equivalent to ~P V ~Q.
I need to create a date range in a table that houses transaction information. The table updates sporadically throughout the week from a manual process. Each time the table is updated transactions are added up to the previous Sunday. For instance, the upload took place yesterday and so transactions were loaded through last Sunday (Feb 26th). If it had been loaded on Wednesday it would still be dated for Sunday. The point is that I have a moving target with my transactions and also when the data is loaded to the table. I am trying to fix my look back period to the date of the latest transaction then go three weeks back. Here is the query that I came up with:
SELECT distinct TransactionDate
FROM TransactionTABLE TB
inner join (
SELECT distinct top 21 TransactionDate FROM TrasactionTABLE ORDER BY TransactionDate desc
) A on TB.TransactionDate = A.TransactionDate
ORDER BY TB.TransactionDate desc
Technically this code works. The problem that I am running into now is when there were no transactions on a given date, such as bank holidays (in this case Martin Luther King Day), then the query looks back one day too far.
I have tried a few different options including MAX(TransactionDate) but if I use that in a sub-query or CTE then use the new value in a WHERE statement as a reference I only get the max value or the value I subtract that statement by. For instance if I say WHERE TransactionDate >= MAX(TransactionDate)-21 and the max date is Feb 26th then the result is Feb 2nd instead of the range of dates from Feb 2nd through Feb 26th.
IN SUMMARY, what I need is a date range looking three weeks back from the date of the latest transaction date. This is for a daily report so I cannot hardcode the date in. Since I am also using Excel Connections the use of Declare statements is prohibited.
Thank you StackOverflow gurus in advance!
You could use something like this:
;with n as (select n from (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) t(n))
, dates as (
select top (21)
[Date]=convert(date,dateadd(day, row_number() over (order by (select 1))-1
, dateadd(day,-20,(select max(TransactionDate) from t) ) ) )
from n as deka
cross join n as hecto
order by [Date]
)
select Date=convert(varchar(10),dates.date,120) from dates
rextester demo: http://rextester.com/ZFYV25543
returns:
+------------+
| Date |
+------------+
| 2017-02-06 |
| 2017-02-07 |
| 2017-02-08 |
| 2017-02-09 |
| 2017-02-10 |
| 2017-02-11 |
| 2017-02-12 |
| 2017-02-13 |
| 2017-02-14 |
| 2017-02-15 |
| 2017-02-16 |
| 2017-02-17 |
| 2017-02-18 |
| 2017-02-19 |
| 2017-02-20 |
| 2017-02-21 |
| 2017-02-22 |
| 2017-02-23 |
| 2017-02-24 |
| 2017-02-25 |
| 2017-02-26 |
+------------+
I just found this for looking up dates that fall within a given week. The code can be manipulated to change the week start date.
select convert(datetime,dateadd(dd,-datepart(dw,convert(datetime,convert(varchar(10),DateAdd(dd,-1/*this # changes the week start day*/,getdate()),101)))+1/*this # is used to change the week start date*/,
convert(datetime,convert(varchar(10),getdate(),21))))/*also can enter # here to change the week start date*/
I've included a screenshot of the results if you were to include this with a full query. This way you can see how it looks with a range of dates. I did a little manipulation so that the week starts on Monday and references Monday's date.
Since I am only looking back three weeks a simple GETDATE()-21 is sufficient because as the query moves forward through the week it will look back 21 days and pick the Monday at the beginning of the week as my start date.
Apologies in advance if this question is badly worded!
I have a MySQL table which has a datetime field. How would one count the number of occurrences of each day name, for distinct weeks?
Here is the query I'm trying, and the result it gives from just over 2 weeks of data. It is (obviously) counting every occurrence for each record, whereas I want the output to be either 2 or 3.
SELECT dayname(datetime), COUNT(dayofweek(datetime))
FROM mytable GROUP BY dayofweek(datetime);
+-------------------+----------------------------+
| dayname(datetime) | count(dayofweek(datetime)) |
+-------------------+----------------------------+
| Monday | 404 |
| Tuesday | 275 |
| Wednesday | 251 |
| Thursday | 196 |
| Friday | 201 |
| Saturday | 128 |
+-------------------+----------------------------+
Grouping by week did not solve the problem. I feel as though I need to "count where week is distinct" but I'm not sure if this is possible.
Any guidance is much appreciated, thank you!
Try to count distinct values (date part only) of your datetime field. More about COUNT(DISTINCT expr,[expr...]) and DATE(expr) that returns the date part only from datetime field.
SELECT dayname(datetime), COUNT(distinct date(datetime))
FROM mytable GROUP BY dayname(datetime);
You normally group on what you are not counting.
I have a MySQL table looking like this. It's basically a time sheet for tasks.
id | task | user | start | stop | running
------+--------+--------+-----------------------+-----------------------+-----------
1 | 12 | 2 | 2009-10-01 10:05:00 | 2009-10-01 14:23:00 | 0
1 | 13 | 4 | 2009-10-05 08:58:00 | 2009-10-05 12:16:00 | 0
1 | 14 | 3 | 2009-10-05 20:30:00 | 2009-10-05 22:00:00 | 0
I want to sum the time spent:
1) Today
2) Yesterday
3) This week
4) Last week
5) This month
6) Last month
I don't need the queries for each of theese, but just the first one to get me started. I'm not that familiar with different date functions in MySQL, and I think it's difficult to read and navigate through their documentation..
It's not THAT difficult to navigate through MySQL documentation.
You need TIMEDIFF() and TIME_TO_SEC functions.
select SUM(TIME_TO_SEC(TIMEDIFF(stop, start))) from my_table
where start >= CURRENT_DATE() and stop <= CURRENT_DATE() + INTERVAL 1 DAY
will get you total time (in seconds) spent on tasks today. Look at DATE_SUB() if you're going to specify criteria for other ranges (e.g. last month, etc) in MySQL instead of supplying them as parameters to your query.
SELECT 'TODAY' Date, SUM(TIME_TO_SEC(TIME_DIFF(stop - start))) TimeSpent
FROM table1
WHERE start >= CURDATE()
AND stop < CURDATE() + INTERVAL 1 DAY