Get records after a certain time in PostgreSQL - sql

I have a table that looks like this:
id | flight_number | departure_time | arrival_time
---+---------------+----------------+-------------
1 | UAL123 | 07:00:00 | 08:30:00
---+---------------+----------------+-------------
2 | AAL456 | 07:30:00 | 08:40:00
---+---------------+----------------+-------------
3 | SWA789 | 07:45:00 | 09:10:00
I'm trying to figure out an SQL query that can get upcoming flights based on departure time given the current time. For instance, at 07:20, I would like to return AAL456, SWA789 since those flights have not departed yet. At 07:40, I would like to just return SWA789. What is a good way to do this?

Well, you can use LOCALTIME to get the current time. So, if the departure_time is stored as a time, then:
select t.*
from t
where t.departure_time > localtime;
This assumes no time zone information is part of the time value. Also, it will return no flights after the last flight has departed for a day (which is consistent with the phrasing of your question).

Related

looking for solution timestamp postgresql

hello my friends I got tired of looking for a solution I have a postgresql database that has a timestamp column I want to extract the values ​​this way
2010-01-01 14:34:43
without the milliseconds how to do this I want it
2010-01-01 14:34:43
and he shows me like this
2010-01-01 14:34:43.267543
If you want to discard the milliseconds you can use date_trunc():
date_trunc('second', mytimestamp)
On the other hand if you want to round to the closest second, you can cast to timestamp(0):
mytimestamp::timestamp(0)
Demo on DB Fiddle - I used a timestamp whose tens of seconds is greater than 5 to make the test representative:
select
mytimestamp,
date_trunc('second', mytimestamp) trunc_mytimestamp,
mytimestamp::timestamp(0) round_mytimestamp
from (values('2010-01-01 14:34:43.567543'::timestamp)) as t(mytimestamp)
mytimestamp | trunc_mytimestamp | round_mytimestamp
:------------------------- | :------------------ | :------------------
2010-01-01 14:34:43.567543 | 2010-01-01 14:34:43 | 2010-01-01 14:34:44

How to go between a set of dates and times

I have a set of data where one column is date and time. I have been asked for all the data in the table, between two date ranges and within those dates, only certain time scale. For example, I was data between 01/02/2019 - 10/02/2019 and within the times 12:00 AM to 07:00 AM. (My real date ranges are over a number of months, just using these dates as an example)
I can cast the date and time into two different columns to separate them out as shown below:
select
name
,dateandtimetest
,cast(dateandtimetest as date) as JustDate
,cast(dateandtimetest as time) as JustTime
INTO #Test01
from [dbo].[TestTable]
I put this into a test table so that I could see if I could use a between function on the JustTime column, because I know I can do the between on the dates no problem. My idea was to get them done in two separate tables and perform an inner join to get the results I need
from #Test01
WHERE justtime between '00:00' and '05:00'
The above code will not give me the data I need. I have been racking my brain for this so any help would be much appreciated!
The test table I am using to try and get the correct code is shown below:
|Name | DateAndTimeTest
-----------------------------------------|
|Lauren | 2019-02-01 04:14:00 |
|Paul | 2019-02-02 08:20:00 |
|Bill | 2019-02-03 12:00:00 |
|Graham | 2019-02-05 16:15:00 |
|Amy | 2019-02-06 02:43:00 |
|Jordan | 2019-02-06 03:00:00 |
|Sid | 2019-02-07 15:45:00 |
|Wes | 2019-02-18 01:11:00 |
|Adam | 2019-02-11 11:11:00 |
|Rhodesy | 2019-02-11 15:16:00 |
I have now tried and got the data to show me information between the times on one date using the below code, but now I would need to make this piece of code run for every date over a 3 month period
select *
from dbo.TestTable
where DateAndTimeTest between '2019-02-11 00:00:00' and '2019-02-11 08:30:00'
You can use SQL similar to following:
select *
from dbo.TestTable
where (CAST(DateAndTimeTest as date) between '2019-02-11' AND '2019-02-11') AND
(CAST(DateAndTimeTest as time) between '00:00:00' and '08:30:00')
Above query will return all records where DateAndTimeTest value in date range 2019-02-11 to 2019-02-11 and with time between 12AM to 8:30AM.

Database Table Design / Setup

I'm trying to setup a PostgreSQL database for a calendar app, and was wondering what would be the preferred way to set up one of the tables.
If I want to have to have multiple users, would the best way to setup the table be:
UserID | Start Time | End Time | Activity |
Or would it be better to do:
User ID | Activity | 8am | 8:30am | 9am | ...| 12am | ... | 7:30am |
The time granularity could be 15 min or 5 min too if that would be the better choice.
The first way would likely be cleaner, but ideally I don't want to let things overlap, but the second way may be more difficult to work with?
Your 1st example is better. But, minimum of 3 tables.
User - you define it.
Timetable: RowID | UserID | Start Time (datetime) | End Time (datetime) | ActivityID
Activity - you define what activity details go in.

TSQL reduce the amount of data returned by a query to a parametric defined sample

I have a table containing a large amount of data which is stored on change.
tbl_bigOne
----------
timestamp | var01 | var02 | ...
2016-01-14 15:20:21 | 10.1 | 100.6 | ...
2016-01-14 15:20:26 | 11.2 | 110.3 | ...`
2016-01-14 15:21:27 | 52.1 | 620.1 | ...
2016-01-14 15:35:00 | 13.5 | 230.6 | ...
...
2016-01-15 09:18:01 | 94.4 | 140.0 | ...
2016-01-15 10:01:15 | 105.3 | 188.7 | ...
...
and so on for years of data
What I would like to obtain is a query/stored procedure that given two datetime references (date_from and date_to) gives the required selected data.
Now, the query just mentioned is pretty straight forward what I would also like to achieve is to set the maximum number of rows returned per day (if data is available) while doing the average of the values.
Let's give a few examples:
date_from: 2016-01-14 00:00:00
date_to: 2016-01-20 23:59:59
max_points:12
in this case the time windows is of 7 days and in this one i would like to have a maximum of 12 rows for each days of the 7 day window, giving a max total of 84 rows whilst doing the average from all the grouping done since, the data for each day is now partitioned by 12.
It is possible to see this partitioning as if every hour worth of data for that specific day is averaged, generating one row of the 12 required for a day.
date_from: 2016-01-14 00:00:00
date_to: 2016-01-14 23:59:59
max_points:1440
in this case the time window is one day worth and, if available, i would like to have a maximum of 1440 rows (for each day) for the selected period.
In this way the parameter defines the maximum number of rows for each day. The minimum time window is one day nothing below that.
Can something like this be achieved just using TSQL?
Thank you.
edit for taking care of the observations raised by #Thorsten Kettner
Use the analytic function ROW_NUMBER() to number the matching rows per day. Then only keep rows up to the given limit. If you want the rows arbitrarily chosen when there exist more than needed, then number the rows in random order using NEWID().
select timestmp, var01, var02, var03
from
(
select
mytable.*,
row_number() over (partition by convert(date, timestmp) order by newid()) as rn
from mytable
where convert(date, timestmp) between #start_date and #end_date
) numbered
where rn <= #limit
order by timestmp;

Design Hours of Operation SQL Table

I am designing a SQL table to store hours of operation for stores.
Some stores have very simple hours: Monday to Sunday from 9:30AM to 10:00PM
Others are little more complicated. Please consider the following scenario:
Monday: Open All Day
Tuesday: 7:30AM – 2:30PM & 4:15PM – 11:00 PM
Wednesday: 7:00PM – 12:30 AM (technically closing on Thursday morning)
Thursday: 9:00AM – 6:00PM
Friday: closed.
How would you design the table(s)?
EDIT
The hours will be used to showing if a store is open at a user selected time.
A different table can probably handle any exceptions, such as holidays.
The store hours will not change from week to week.
A table like this would be easy for both the output you posted, as well as just firing a bit back (open? yes/no):
Store | Day | Open | Closed
---------------------------
1 | 1 | 0000 | 2400
1 | 2 | 0730 | 1430
1 | 2 | 1615 | 2300
...
Features:
Using 24-hour isn't necessary, but makes math easier.
Store ID would presumably join to a lookup table where you stored Store information
Day ID would translate to day of week (1 = Sunday, 2 = Monday, etc.)
To query for your dataset, just:
SELECT Day, Open, Close... (you'd want to format Open/Close obviously)
To query IsOpen?, just:
SELECT CASE WHEN #desiredtime BETWEEN Open AND Closed THEN 1 ELSE 0 END
FROM table
WHERE store = #Store
Think of it more as defining time frames, days / weeks are more complex, because they have rules and defined start and stops.
How would you define a timeframe?
one constraint (Start[Time and Day]), one reference 'Duration' (hours, minutes,.. of the span)*. Now the shifts (timeframes) can span multiple days and you don't have to work complex logic to extract and use the data in calculations.
**Store_Hours**
Store | Day | Open | DURATION
---------------------------
1 | 1 | 0000 | 24
1 | 2 | 0730 | 7
1 | 2 | 1615 | 6.75
...
1 | 3 | 1900 | 5.5
Do you have to do more than just store and display it?
I think a design which needs to tell if a store is open at a particular time would have to be informed by all of the possibilities, otherwise, you will end up not being able to accommodate something.
What about holiday exceptions?
I would consider storing them as intervals based on a base time (minutes since time 0 on a week).
So 0 is midnight on Monday.
Interval 1 would be 0 - 1440
Interval 2 would be 1890 - 2310
etc.
You could easily convert a user selected time into a minute offset and determine if a store was open.
Your only problem remaining would be interpretation in display for friendly display (probably some extensive logic, but not impossible) and overlap at time 10080 -> 0.