I am working on a project in a company. I am trying to solve this query but I could not.
My tables are:
Appointments:
doctorId patientId patientName fromDateTime toDateTime
-------- --------- ----------- --------------------- ---------------------
56 1 fghfgh 3/23/2012 12:15:00 PM 3/23/2012 01:15:00 PM
56 2 asdadf 3/23/2012 01:15:00 PM 3/23/2012 02:15:00 PM
56 3 werwr 3/23/2012 09:15:00 AM 3/23/2012 10:15:00 AM
57 4 uiyui 3/23/2012 09:15:00 AM 3/23/2012 10:15:00 AM
57 5 asdad 3/23/2012 01:15:00 PM 3/23/2012 02:15:00 PM
This is my timeSchedule table:
id startTime endTime
-- ------------ ------------
1 08:00:00.000 09:00:00.000
2 09:00:00.000 10:00:00.000
3 11:00:00.000 12:00:00.000
4 12:00:00.000 13:00:00.000
5 13:00:00.000 14:00:00.000
6 14:00:00.000 15:00:00.000
7 15:00:00.000 16:00:00.000
Actually there are more values but I think these are enough to solve the problem.
I am comparing patient appointments with this timeSchedule table.
Now suppose if I pass parameter doctorId as 56 and consider today is 23 March then output should be like this:
id startTime endTime
-- --------- --------
1 08:00 AM 09:00 AM
3 11:00 AM 12:00 PM
6 02:00 PM 03:00 PM
7 03:00 PM 04:00 PM
How can I achieve the above result?
Assuming that timeSchedule.startTime and timeSchedule.endTime are both Time data types then it would be something like this...: (if not, you could cast as such).
DECLARE #pDoctorID Int = 56
DECLARE #pDate Date = '3/23/2012'
SELECT * FROM timeSchedule WHERE
NOT Exists (
SELECT doctorid FROM Appointments
WHERE doctorid = #pDoctorID AND
CAST(fromDatetime as Date) = #pDate AND
(
(CAST(fromDatetime as Time) >= timeSchedule.startTime AND
CAST(fromDatetime as Time) <= timeSchedule.endTime)
OR
(CAST(toDatetime as Time) >= timeSchedule.startTime AND
CAST(toDatetime as Time) <= timeSchedule.endTime)
OR
(CAST(toDatetime as Time) <= timeSchedule.startTime AND
CAST(fromDatetime as Time) >= timeSchedule.endTime)
)
)
Which with your sample data returns this:
1 | 08:00:00.00 | 09:00:00.00
4 | 11:00:00.00 | 12:00:00.00
8 | 15:00:00.00 | 16:00:00.00
In essence the query is saying give me any appointment for this doctor where existing appoints do not start or end between the time frames, or start before and end after any of the time slots defined by the timeSchedule table.
Formatting the return times is also a simple matter. See the table in this link for all your options.
Related
I want to create a stored procedure in MySQL, but first, I want to get the query right. However, I keep getting the problem that I can't seem to get the correct id back from my query that correspond with the DateTime stamps that I get back.
this is the table I am trying to get the result from:
id EventId start end
1 1 2019-04-05 00:00:00 2019-04-07 00:00:00
2 2 2020-04-03 00:00:00 2020-04-03 00:00:00
3 3 2020-04-02 00:00:00 2020-04-02 00:00:00
7 1 2020-06-11 00:00:00 2020-06-11 00:00:00
9 2 2020-06-18 00:00:00 2020-06-18 00:00:00
10 3 2020-06-11 00:00:00 2020-06-11 00:00:00
11 3 2020-06-07 00:00:00 2020-06-07 00:00:00
query:
SELECT DISTINCT Eventid, MIN(start), id
from date_planning
WHERE `start` >= NOW()
GROUP BY Eventid
this gives me the following result
EventId Min(start) id
1 2020-06-11 00:00:00 3
2 2020-06-18 00:00:00 9
3 2020-06-07 00:00:00 10
but these are the correct ids that belong to those DateTimes:
EventId Min(start) id
1 2020-06-11 00:00:00 7
2 2020-06-18 00:00:00 9
3 2020-06-07 00:00:00 11
You want the row with the minimum "future" date for each eventId. To solve this greatest-n-per-group problem, you need to filter rather than aggregate. Here is one option using a correlated subquery:
select dt.*
from date_planning dt
where dt.start = (
select min(dt1.start)
from date_planning dt1
where dt1.eventId = dt.eventId and dt1.start >= now()
)
For performance, you need an index on (eventId, start).
I have table like this,
tid vid emp_id stop_time dates
----------------------------------------
1 5680 6 01:00 am 2017-05-19
2 5680 6 04:00 am 2017-05-19
3 5680 3 07:00 am 2017-05-19
4 5680 3 05:00 pm 2017-05-19
5 5680 6 08:00 am 2017-05-20
I want the particular value, for above this e.g i need this values 04:00 am and 05:00 pm and 08:00 am. That means i need last enter value of emp_id also particular dates based.
Demo data:
http://sqlfiddle.com/#!9/3f6e59/1
use subquery
select * from third_table
where tid in (select max(tid) from third_table
where dates between '2017-05-19' and '2017-05-20' group by emp_id,dates)
I have two tables and trying to find records between start_date & end_date.
campaign table
campaign_id campaign_name start_date end_date
*********** ************* ********** ********
1 Deacon Navarro 2015-10-28 00:00:00 2015-10-31 00:00:00
2 Emily Oliver 2015-10-29 00:00:00 2015-11-04 00:00:00
statistic table
id campaign_id comments likes created_date
** *********** ******** ***** ************
1 1 14 24 2015-10-28 00:00:00
2 1 34 12 2015-10-29 00:00:00
3 1 23 12 2015-10-30 00:00:00
4 1 23 24 2015-10-31 00:00:00
5 1 21 45 2015-11-01 00:00:00
6 2 12 17 2015-10-31 00:00:00
7 2 23 12 2015-11-01 00:00:00
Now I want to find all records from statistic table where campaign_id=1 and created_date is between created_date to end_date from campaign table.
I need this output:
1 1 14 24 2015-10-28 00:00:00
2 1 34 12 2015-10-29 00:00:00
3 1 23 12 2015-10-30 00:00:00
4 1 23 24 2015-10-31 00:00:00
I have written very basic select query to find start_date & end_date from campaign table
SELECT start_date, end_date FROM campaign WHERE campaign_id = '1'
and I got this result:
start_date end_date
********** ********
2015-10-28 00:00:00 2015-10-31 00:00:00
but now I don't know how to find records from statistic table where created_date is between above start_date & end_date
Hope you are understand. I am not good with MySQL because I have just stared to learning so I need help If possible :)
Thanks.
Try this :
SELECT statistic.*
FROM statistic, campaign
WHERE
campaign.campaign_id = '1'
AND campaign.campaign_id = statistic.campaign_id
AND statistic.created_date BETWEEN campaign.start_date AND campaign.end_date
try this way
SELECT statistic.*
FROM statistic
INNER JOIN campaign ON statistic.campaign_id= campaign.campaign_id;
WHERE statistic.created_date BETWEEN campaign.start_date AND campaign.end_date
Try this :
SELECT s.*
FROM statistic AS s
INNER JOIN campaign AS c ON s.campaign_id = c.campaign_id;
WHERE c.campaign_id = 1
AND s.created_date BETWEEN c.start_date AND c.end_date
For more information about JOIN syntax here.
I have a mysql db which I use to return amounts of orders by hour in a specific day. I use this SELECT statement for that.
select
hour(datains),sum(valore)
from
ordini
where (stato=10 or stato = 1 ) and DATE(datains) = DATE_SUB(CONCAT(CURDATE(), ' 00:00:00'), INTERVAL 0 DAY)
group by hour(datains)
order by
id DESC
It returns:
+--------------+---------------+
| hour datains | valore |
| 12 | 34 |
| 11 | 56 |
| 10 | 134 |
+-------------------------------
Now I need to have columns for a certain number of days, like this.
+--------------+---------------+--------------+--------------+
| hour datains | 01-01-2014 | 02-01-2014 | 03-01-2014 |
| 12 | 34 | 34 | 77 |
| 11 | 56 | 0 | 128 |
| 10 | 134 | 66 | 12 |
+------------------------------+-----------------------------+
Is this possible?
It seems you have a table ordini with columns datains, valore, and stato.
Perhaps you can try this query to generate hour-by-hour aggregates for a three days' worth of recent sales, but not including today.
SELECT DATE_FORMAT(datains, '%Y-%m-%d %H:00') AS hour,
SUM(valore) AS valore
FROM ordini
WHERE (stato = 1 OR stato = 10)
AND datains >= CURRENT_DATE() - INTERVAL 3 DAY
AND datains < CURRENT_DATE
GROUP BY DATE_FORMAT(datains, '%Y-%m-%d %H:00')
ORDER BY DATE_FORMAT(datains, '%Y-%m-%d %H:00')
This will give you a result set with one row for each hour of the three days, for example:
2014-01-01 10:00 456
2014-01-01 11:00 123
2014-01-02 10:00 28
2014-01-02 11:00 350
2014-01-02 12:00 100
2014-01-02 13:00 17
2014-01-03 10:00 321
2014-01-03 11:00 432
2014-01-03 12:00 88
2014-01-03 13:00 12
That's the data summary you have requested, but formatted row-by-row. Your next step is to figure out an appropriate technique to pivot that result set, formatting it so some rows become columns.
It happens that I have just written a post on this very topic. It is here:
http://www.plumislandmedia.net/mysql/sql-reporting-time-intervals/
Query for VB6 and MS Access
Table:-
User Id LogDate LogTime
1 1/1/2010 9:00
1 1/1/2010 10:00
1 1/1/2010 11:29
1 2/1/2010 10:00
2 2/1/2010 22:00
2 3/1/2010 11:00
Need to display as:-
User Id LogDate LogTime LogDate LogTime
1 1/1/2010 9:00 1/1/2010 10:00
1 1/1/2010 11:29 2/1/2010 10:00
2 2/1/2010 22:00 3/1/2010 11:00
You need to use a sub-query to find the next date for a user, something like:
SELECT tblStackOverflowTimeQuery.lngUserId, tblStackOverflowTimeQuery.datLogDateTime,
(SELECT TOP 1 tblStackOverflowTimeQuery2.datLogDateTime
FROM tblStackOverflowTimeQuery AS tblStackOverflowTimeQuery2
WHERE tblStackOverflowTimeQuery.lngUserId = tblStackOverflowTimeQuery2.lngUserId
AND tblStackOverflowTimeQuery2.datLogDateTime > tblStackOverflowTimeQuery.datLogDateTime
ORDER BY tblStackOverflowTimeQuery2.datLogDateTime
) AS datEndDateTime
FROM tblStackOverflowTimeQuery
ORDER BY tblStackOverflowTimeQuery.lngUserId, tblStackOverflowTimeQuery.datLogDateTime;
That'll give the following:
lngUserId datLogDateTime datEndDateTime
1 01/01/2010 09:00:00 01/01/2010 10:00:00
1 01/01/2010 10:00:00 01/01/2010 11:29:00
1 01/01/2010 11:29:00 02/01/2010 10:00:00
1 02/01/2010 10:00:00
2 02/01/2010 22:00:00 03/01/2010 11:00:00
2 03/01/2010 11:00:00
which is not exactly what you wanted, but it's a start.
It would be easiest to do these things using code, but that would depend on how you want to use it. Presumably there's nothing in your data to indicate which entry is the start and which is the end.