I am working with PostgreSQL 8.4.4. I am calculating time difference between two Unix time-stamps using PostgreSQL's age function. I am getting the output as expected. The only thing I want is to convert the time difference in UPPERCASE.
For example,
select coalesce(nullif(age(to_timestamp(1389078075), to_timestamp(1380703432))::text,''), UPPER('Missing')) FROM transactions_transactions WHERE id = 947
This query giving the result as
3 mons 4 days 22:17:23
But I want this output to be like
3 MONTHS 4 DAYS 22:17:23
Note: I am using this for dynamic report generation purpose. So I cannot convert it to UPPERCASE after fetching from database. I want it to be in UPPERCASE at the time of coming from database itself, i.e., in the query.
PostgreSQL's upper() function should be use
SELECT upper(age(to_timestamp(1389078075), to_timestamp(1380703432))::text)
FROM transactions_transactions WHERE id = 947
as per OP's comment and edit
select upper(coalesce(nullif(age(to_timestamp(1389078075), to_timestamp(1380703432))::text,''), UPPER('Missing')))
Related
I'm making a Power BI report where data that I need to show is stored in a PostgreSQL database.
In the table where I query there is data from 4 years ago until today, but for my report I only need the last week of records (I know that I can filter using Power BI but my goal is make the lighter query as possible).
The fields of the database related to time, are in UNIX Timestamp, so I'm filtering it now by this way:
SELECT
DATABASE.INCIDENT_NUMBER
,DATABASE.SUBMITTER
,DATABASE.CREATE_DATE
,DATABASE.MODIFIED_DATE
,DATABASE.CLOSED_DATE
,DATABASE.SUBJECT
FROM
DATABASE
WHERE
1643670000 < DATABASE.CREATE_DATE
ORDER BY DATABASE.INCIDENT_NUMBER, DATABASE.CREATE_DATE ASC
That is fine, but I want to improve it making a dynamic query which returns the records from last week till today, without putting a constant of UNIX timestamp.
How can I make that?
That's an excellent example why it is a bad idea to store timestamps as numbers. The correct data type is timestamp or timestamp with time zone.
If you had used the correct data type, your condition would be as simple as
WHERE current_date - 7 < database.create_date
But with numbers, you have to convert back and forth:
WHERE to_timestamp(EXTRACT('epoch' FROM current_date) - 7) < database.create_date
I am select data from a table with different timestamps and I need to group the data by 7 days intervals without using the week keyword.
You can easily use the DAYS function and divide it by 7 like
GROUP BY DAYS(my_dt_column) / 7
See https://www.ibm.com/support/knowledgecenter/en/SS6NHC/com.ibm.swg.im.dashdb.sql.ref.doc/doc/r0000789.html
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.
I am new to Cognos and I am trying to add a filter to a column that only allows rows that are in between Yesterday at 4 AM and today at 3 AM. I have a working query in db2 but when I try to add it to the filter in Cognos I get a parsing error. Also, I found in the properties that the data type for the column I am trying to filter to be Unknown (Unsupported) type. I started off by creating two Data Item Expressions for each time frame I am trying to limit the data by. But I got a parsing error on the first one:
[Presentation Layer].[Cr dtime]=timestamp(current date) - 1 day + 4 hour
This works in my db2 local test database but doesn't even compile in Cognos. I also tried casting the column into a timestamp but that isn't working either. Any help is appreciated. I also tried using the _add_days function but I still get a parsing error. Also sampling the column I get values that appear to be timestamps as this string: 2016-01-02T11:11:45.000000000
Eventually if I get the two filters working I expect the original filter to be close to this syntax:
[Presentation Layer].[Cr dtime] is between [Yesterday 4AM] AND [Today 3AM]
Here is your filter:
[Presentation Layer].[Cr dtime] between
cast(_add_hours(_add_days(current_date,-1),4),timestamp)
and
cast(_add_hours(current_date,3),timestamp)
This works because current_date in Cognos does not have a time component. If you were to cast it directly to a timestamp type you would see the time part of the date as 12:00:00.000 AM, or midnight. Knowing this we can then simply add how much time after midnight we want, cast as a timestamp type and use this in the filter.
How would i write a statement that would make specific group by's looking at the monthly date range/difference. Example:
org_group | date | second_group_by
A 30.10.2013 1
A 29.11.2013 1
A 31.12.2013 1
A 30.01.2015 2
A 27.02.2015 2
A 31.03.2015 2
A 30.04.2015 2
as long es there isnt a monthly date_diff > 1 it should be in the same second_group_by. I hope its clear enough for you to understand, the column second_group_by should be generated by the user...it doesnt exists in the table.
date diff between which rows though?
If you just want to separate years (or months or weeks) use
GROUP BY DATEPART(....)
That's Sybase or SQL Server but other SQLs will have equivalent.
If you have specific data ranges, get them into a table with start and end date-time and a monotonically increasing integer, join to that with a BETWEEN and GROUP BY the integer.