Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have this data from a sql table, but do not know how to put into the table structure below. What is the best method for converting the data to that structure?
2011/07/13 Wednesday 10:00 1
2011/07/13 Wednesday 10:30 1
2011/07/13 Wednesday 11:00 0
...
2011/07/15 Friday 10:00 1
2011/07/15 Friday 10:30 0
2011/07/15 Friday 11:00 0
2011/07/15 Friday 11:30 1
...
2011/07/16 Saturday 09:00 0
2011/07/16 Saturday 09:30 1
2011/07/16 Saturday 10:00 1
...
2011/07/17 Sunday 10:00 1
2011/07/17 Sunday 10:30 0
2011/07/17 Sunday 11:00 0
2011/07/17 Sunday 11:30 1
...
If your RDBMS doesn't support PIVOT, you could do something like this:
SELECT
TIME,
(SELECT FLAG FROM SCHED S WHERE DATE = '7/13/2011' AND TIME = SCHED.TIME) AS [7/13/2011],
(SELECT FLAG FROM SCHED S WHERE DATE = '7/14/2011' AND TIME = SCHED.TIME) AS [7/14/2011]
... other date columns ...
FROM
SCHED
This is assuming your table has this structure:
CREATE TABLE SCHED
(
[DATE] date,
TIME char(5),
FLAG tinyint
)
And you probably want to use the date/time functions to calculate dates relative to the current date in your subqueries rather than hard-code them like I have, but you get the idea :-)
Use the pivot operator (MS-SQL)
See here:
How to transform a datatable to a ReportingService-like matrix?
Related
I"m dealing with a dataset with 4 week sales data (data will be refreshed every hour) and need to observer for abnormality
I think I'll go with a basic approach, to compare with average numbers and I'm trying to figure out how to best break this down so I can answer some questions below
On average, how many orders received at 9:00 , 15:00 or 16:00 past 30 days
On average, how many orders received at 9:00 every Wednesday (past 4 Wednesdays), at 15:00 every Thursday (past 4 Thursdays),
Not sure how do we go about this (after breaking date/time down to Hour and Weekday columns)
date
order ID
order hour
order weekday
10/07/2022 10:26:12 PM
1111
22
6
10/07/2022 10:27:12 PM
2222
22
6
....
....
....
....
19/07/2022 11:34:19 AM
9998
11
1
19/07/2022 11:34:35 AM
9999
11
1
I would love to get your advice please
Thanks
I've ended up going with a tedious approach.
#get current hour & weekday
now=datetime.datetime.now()
today=datetime.date.today()
current_hour=now.hour
current_weekday=today.weekday()
#create a DF with orders from the same hour & weekday window
same_hour_weekday_df=order_df[(order_df.order_hour==current_hour ) & (order_df.order_weekday==current_weekday) ]
#calculate avg orders generated from the past weeks within the same hour and weekyday timeframe
orders_same_hour_weekday=same_hour_weekday_df['order_created_at'].count()
same_hour_weekday_periods=same_hour_weekday_df['order_week'].nunique()
avg_orders_same_hour_weekday=orders_same_hour_weekday/same_hour_weekday_periods
I am new to sql and this is my first ever question. I am working with a sample database that I want to extract specific information from to display as a dashboard. The issue is that I can do this partially but I cannot seem to figure it out properly.
``SELECT
S_date as date,
p_time as time,
process_id as process,
sc_gun as scannumb,
sum(line_qty) as linetotal,
sum(area_qty) as areatotal
FROM dbfile6
WHERE
process_id in('0010','0020','0030')
and sc_gun in = ('10','20','30','40','50')
and s_date = curdate() - 1 and p_time between '22:00:00' and '23:59:59'
or s_date = curdate() and p_time between '00:00:00' and '06:00:00'
GROUP BY p_time, s_date, process_id, sc_gun
ORDER BY s_date, process_id
What do I want to display?
I can do partially where I want it to work to yesterdays date (s_date) recurring but I want this to only happen Monday to Friday, skipping the weekend so when we are on Monday, it looks at Fridays data from the database.
I want to show the time as a range, a night range. The range is 20:00:00 - 06:00:00. The range is tricky as it crosses over to the next day, this could work for Monday to Thursday but not Friday as there is no working weekend so what would I do here? In addition to this, I can sum up the values successfully and display it as averages for each process but then once I add the time in, it displays each result individually.
The table below is what it looks like in the database, however as mentioned earlier, the desired result is for each process to have the line_qty and area_qty summed up by time range and a day and night cycle.
s_date
p_time
process_id
sc_gun
line_qty
area_qty
04/05/2022
04:49:52
0010
10
2
12
03/05/2022
11:50:00
0010
10
5
14
03/05/2022
19:50:00
0010
10
7
16
03/05/2022
13:50:00
0020
20
4
6
03/05/2022
19:50:00
0010
10
7
16
I have a db with 6 tables. Each table has a list of date and datetime columns as shown below
Table 1 Table 2 .... Table 6
Date_of_birth Exam_date exam_datetime Result_date Result_datetime
2190-01-13 2192-01-13 2192-01-13 09:00:00 2194-04-13 2194-04-13 07:12:00
2184-05-21 2186-05-21 2186-05-21 07:00:00 2188-02-03 2188-02-03 09:32:00
2181-06-17 2183-06-17 2183-06-17 05:00:00 2185-07-23 2185-07-23 12:40:00
What I would like to do is shift all these future days back to the past date (definitely has to be less than the current date) but retain the same chronological order. Meaning, we can see that the person was born first, then he took the exam, and finally, he got his results.
In addition, I should be able to revert the changes and get back the future dates again.
I expect my output to be something like below
Stage 1 - shift back to old days (it can be any day but it has to be in the past and retain chronological order)
Table 1 Table 2 .... Table 6
Date_of_birth Exam_date exam_datetime Result_date Result_datetime
1990-01-13 1992-01-13 1992-01-13 09:00:00 1994-04-13 1994-04-13 07:12:00
1984-05-21 1986-05-21 1986-05-21 07:00:00 1988-02-03 1988-02-03 09:32:00
1981-06-17 1983-06-17 1983-06-17 05:00:00 1985-07-23 1985-07-23 12:40:00
Stage 2 - Shift forward to future days as how it was earlier
Table 1 Table 2 .... Table 6
Date_of_birth Exam_date exam_datetime Result_date Result_datetime
2190-01-13 2192-01-13 2192-01-13 09:00:00 2194-04-13 2194-04-13 07:12:00
2184-05-21 2186-05-21 2186-05-21 07:00:00 2188-02-03 2188-02-03 09:32:00
2181-06-17 2183-06-17 2183-06-17 05:00:00 2185-07-23 2185-07-23 12:40:00
Subtract two centuries:
update table1
set date_of_birth = date_of_birth - interval '200 year';
You can do something similar for all the other dates.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am trying to find # of records in next 30 days from start date for each record
I have a table:
Patid Start_date
1234 1/1/2015
1234 1/10/2015
1234 1/30/2015
1234 2/19/2015
1234 3/5/2015
1234 3/6/2015
1234 3/7/2015
I want to write a simple sql query that should give me the following result:
patid: Start_Date #of Records in Next 30 Days
1234 1/1/2015 2
1234 1/10/2015 2
1234 1/30/2015 1
1234 2/19/2015 3
1234 3/5/2015 2
1234 3/6/2015 1
1234 3/7/2015 0
Best Regards,
Sunny
In generic SQL,the easiest way is with a correlated subquery:
select t.*,
(select count(*)
from table t2
where t2.patid = t.patid and
t2.start_date > t.start_date and
t2.start_date <= t.start_date + interval '30 days'
) as Next30Days
from table t;
This uses ANSI standard syntax for the date arithmetic -- a standard mostly observed in the breach. Each database seems to have its own rules for massaging dates.
My initial answer to this problem has been to script it. Instead of using SQL, I've dipped into Python and normalised them. I am curious whether anyone can come up with a solution using SQL though.
If a date occurs outside of business hours, I want to normalise the date to the next working day. I'll keep this really simple and say that business hours is 9am to 6pm Monday to Friday. Anything outside of those hours is outside of business hours.
What should happen the dates is that they are changed so that 2pm on Saturday becomes 9am on Monday morning (the first legitimate time in the business week). 7pm on a Wednesday becomes 9am Thursday morning. etc. etc. Let's ignore holidays.
Sample data:
mysql> select mydate from mytable ORDER by mydate;
+---------------------+
| mydate |
+---------------------+
| 2009-09-13 17:03:09 |
| 2009-09-14 09:45:49 |
| 2009-09-15 09:57:28 |
| 2009-09-16 21:55:01 |
+---------------------+
4 rows in set (0.00 sec)
The first date is a Sunday so it should be normalised to 2009-09-14 09:00:00
The second date is fine, it's at 9am on a Monday.
The third date is fine, it's at 9am on a Tuesday.
The fourth date is at 9pm (outside of our 9am to 6pm business hours) on a Wednesday and should be transformed to 9am Thursday morning.
I think you're better off with your Python solution ... but I like challenges :)
select mydate
, case dayadjust
-- BUG
-- when 0 then mydate
-- BUG
when 0 then case
when hour(mydate)<9
then date_add(from_days(to_days(mydate)),
INTERVAL 9 HOUR)
else mydate
end
-- BUG SQUASHED
else date_add(from_days(to_days(mydate) + dayadjust),
INTERVAL 9 HOUR)
end as mynewdate
from (
select mydate
, case
when addday>=moreday then addday
else moreday
end as dayadjust
from (
select mydate
, weekday(mydate) as w
, hour(mydate) as h
, case weekday(mydate)
when 6 then 1
when 5 then 2
when 4 then
case
when hour(mydate) >= 18 then 3
else 0
end
else 0
end as addday
, case when hour(mydate)>=18 then 1 else 0 end as moreday
from mytable
order by mydate
) alias1
) alias2
Tested on MySQL
$ mysql tmp < phil.sql
mydate mynewdate
2009-09-12 17:03:09 2009-09-14 09:00:00
2009-09-12 21:03:09 2009-09-14 09:00:00
2009-09-13 17:03:09 2009-09-14 09:00:00
2009-09-14 09:45:49 2009-09-14 09:45:49
2009-09-15 09:57:28 2009-09-15 09:57:28
2009-09-16 21:55:01 2009-09-17 09:00:00
2009-09-17 11:03:09 2009-09-17 11:03:09
2009-09-17 22:03:09 2009-09-18 09:00:00
2009-09-18 12:03:09 2009-09-18 12:03:09
2009-09-18 19:03:09 2009-09-21 09:00:00
2009-09-19 06:03:09 2009-09-21 09:00:00
2009-09-19 16:03:09 2009-09-21 09:00:00
2009-09-19 19:03:09 2009-09-21 09:00:00
Not sure why you want to do this, but if it needs to always be true of all data in your database, you need a trigger. I would set up a table to pull from that specifies the business hours and you can use that table to determine the next valid business hour day and time. (I might even consider making a table that tells you exactly what the next business day and hour is for each possibility, it's not like this changes a lot, might have to be updated once a year if you change holidays for the next year or if you change the overall business hours. By precalulating, you can probably save time in processing this.). I would also conmtinue to use your script becasue it's better to fix data before it gets entered, but you need the trigger to ensure that data from any source (and sooner or later there will be changes form sources other than your application) meets the data integrity rules.
I don't think you can do it in one query, but you can try this:
-- Mon-Thu, after 17:00
-- Set date = next day, 9:00
UPDATE
myTable
SET
mydate = DATE_ADD(DATE_ADD(DATE(date), INTERVAL 1 DAY), INTERVAL 9 HOUR)
WHERE
TIME(mydate) >= 17
AND DAYOFWEEK(mydate) IN (1,2,3,4)
-- Mon-Fri, before 9:00
-- Set date = the same day, 9:00
UPDATE
myTable
SET
mydate = DATE_ADD(DATE(date), INTERVAL 9 HOUR)
WHERE
TIME(mydate) < 9
AND DAYOFWEEK(mydate) IN (1,2,3,4,5)
-- Fri, after 17:00, Sat, Sun
-- Set date = monday, 9.00
UPDATE
myTable
SET
mydate = DATE_ADD(DATE_ADD(DATE(date), INTERVAL 3 DAY), INTERVAL 9 HOUR)
WHERE
(TIME(mydate) >= 17
AND DAYOFWEEK(mydate) = 5)
OR DAYOFWEEK(mydate) IN (6,7)