Get each value's difference from overall min value in Postgres - postgresql

I have a table of data that is in timestamp with time zone format (called "time"). I also have an empty table that takes in interval data type values. For each row in the empty table, I want to insert the interval difference between that row's timestamp in the original data and the overall minimum timestamp value in the original data. I'm trying to do something like this:
INSERT INTO
time_pyramid
SELECT
"time" - MIN("time")
FROM
time_raw;
But it tells me "ERROR: column "time_raw.time" must appear in the GROUP BY clause or be used in an aggregate function". I know I want each timestamp value's interval difference from the table's overall minimum timestamp value, and "time" is not going to end up having duplicate values from this interval conversion, so I don't really think I should use GROUP BY in that context. I also see no reason to use an aggregation function on the first "time", so how can I fix my query to reflect what I want?
Edit: Actually, "Get each value as its interval difference from the min" is a better title for this question

Use min() as a window function:
with time_raw("time") as (
values
('2016-01-11'::timestamp),
('2016-01-01'::timestamp),
('2016-01-21'::timestamp)
)
select
"time"- min("time") over () as interval
from
time_raw;
interval
----------
10 days
00:00:00
20 days
(3 rows)

Related

How can I sum a column by date in KDB Q?

I have a table in KDB with columns date, time, and returns. I need the cumulative returns per day stowed in a new column, but I'm not sure how to separate the sums function by date. This is what I tried:
Table: update cumreturns: sums returns from Table by date where time within (09:30:00;16:00:00)
But I get an evaluation error: date when I run it. Is my syntax off or is there another way I need to approach this?
you need to include the by clause before the 'from' statement, something like this
update cumReturns:sums returns by date from t

how to use the age() function in postgresql

I have a column in the students table called birthdate. i need to find students over the age of 12.
select ......, age(timestamp 'birthdate') as StudentAge
from students
.....
where StudentAge > 11
I dont know if thats the proper syntax or if im using the correct function for the situation
I think most of your confusion comes from unfamiliarity with Postgres's rich type system, and the syntax it uses.
In the page on date/time functions, the age function is listed with two forms. Assuming you want to compare to "today", you want the form with a single argument:
Function: age(timestamp)
Return type: interval
Description: Subtract from current_date (at midnight)
Example: age(timestamp '1957-06-13')
Result: 43 years 8 mons 3 days
So, you have a function which takes a value of type timestamp, and returns a value of type interval.
The example shows the input being specified as timestamp '1957-06-13'; this is just a way of creating a value of type timestamp from a hard-coded value - like creating an object in an object-oriented language. In your query, birthdate is not a hard-coded value, it's the name of a column, so this is not the syntax you want. If the column is of type timestamp, you can just use age(birthdate) directly; if not, you might need to convert it, e.g. age(CAST(birthdate AS timestamp)).
The output is of type interval, not a number of years, so comparing it against 12 is unlikely to do what you want. Instead, you should compare it against another interval value. Similar to the timestamp '1957-06-13' example, you can write interval '12 years' to directly create an interval value representing 12 years.
So your comparison would look like age(birthdate) >= interval '12 years'.
I don't know that tutorial you are talking about, but the documentation has the following to say about column labels:
The entries in the select list can be assigned names for subsequent processing, such as for use in an ORDER BY clause or for display by the client application.
Observe the subsequent here: The SELECT list is (logically) processed after the WHERE clause, so you cannot use column labels there.
You'll have to repeat the expression. This is in accordance with the SQL standard.
Moreover, birthdate is not a string literal, so don't quote it. And remove the timestamp.

Cast varchar as date select distinct top 100

I am trying to fix a query that has come to light in SSRS after the new year. We have an input that comes from another application. It grabs a date and stores it as varchar. The SSRS report then fetches the top 100 'dates' but when 2017 dates have come around, this are not in the top 100.
The existing query is as follows
SELECT DISTINCT TOP (100)
FROM DenverTempData
ORDER by BY Date DESC
The date is stored as VARCHAR. So obviously this query doesn't grab a value such as 01012017 as being a top 100 (over values likes 12312016). I thought maybe I can simply change the datatype on this column to datetime. But the information comes from a flat file and is converted, so it's a little more difficult that that. So I'm hoping to do a select of the distinct top 100 while converting the date column to datetime or just date and grabbing the last 100 dates.
Can someone help with the query syntax? I'm thinking a cast to convert varchar to date, but how do I format with distinct top 100? I'm simply looking to retrieve the last 100 dates in chronological order from a column that is stored as varchar but contains a string representing a date.
Hopefully that makes sense
It is always a bad idea to store a date as string. This is highly culture specific!
You can cast your formatted string-date to a real date like this:
DECLARE #DateMMDDYYYY VARCHAR(100)='12312016';
SELECT CONVERT(DATE,STUFF(STUFF(#DateMMDDYYYY,5,0,'-'),3,0,'-'),110)
After the conversion your sorting (and therefore the TOP 100) should work as expected.
My strong advise: Try to store your dates in a column of a real date type to avoid such hassel!
SELECT DISTINCT TOP 100 (CAST(VarcharColumn as Date) as DateColumn)
FROM TABLE
Order by DateColumn desc

postgreSQL sorting with timestamps

I have the following SQL statement:
SELECT * FROM schema."table"
WHERE "TimeStamp"::timestamp >= '2016-03-09 03:00:05'
ORDER BY "TimeStamp"::date asc
LIMIT 15
What do I expect it to do? Giving out 15 rows of the table, where the timestamp is the same and bigger than that date, in ascending order. But postgres sends the rows in the wrong order. The first item is on the last position.
So has anyone an idea why the result is this strange?
Use simply ORDER BY "TimeStamp" (without casting to date).
By casting "TimeStamp" to date you throw away the time part of the timestamp, so all values within one day will be considered equal and are returned in random order. It is by accident that the first rows appear in the order you desire.
Don't cast to date in the ORDER BY clause if the time part is relevant for sorting.
Perhaps you are confused because Oracle's DATE type has a time part, which PostgreSQL's doesn't.

Comparing two time columns in ASP.NET

I'm rather new to ASP.NET and SQL, so I'm having a tough time trying to figure out how to compare two time columns. I have a timestamped column and then a Now() column in an .mdb database. I need to have a gridview display records that are "Greater than or equal to 3 hours" from the timestamp. Any idea how I can accomplish this?
The Transact-SQL timestamp data type is a binary data type with no time-related values.
So to answer your question: Is there a way to get DateTime value from timestamp type column?
The answer is: No
You need another column of datetime2 type and use > operator to for comparison. You might want to set default value of getutcdate() to set it when each row is inserted.
UPDATE:
Since the column is of datetime type and not timestamp type (there is a type in SQL Server called timestamp, hence the confusion) you can just do
WHERE [TimeCalled] <= DATEADD(hour, -3, GETDATE())
Make sure your server is running in the same timezone as your code. It may be safer to store all dates in UTC. In that case use GETUTCDATE instead on GETDATE
Timestamps are generally used to track changes to records, and are updated every time the record is changed. If you want to store a specific value you should use a datetime field.
If you're using a DateTime Column and you want the result in TSQL try
DATEDIFF(Hour, 'Your DateTime Column here', 'pass Now() here' )
try to execute this example in TSQL:
select DATEDIFF(Hour, '2012-11-10 00:00:59.900', '2012-11-10 05:01:00.100')