How can I write a query in DB2 for following thing:
The difference between current timestamp and a timestamp field in dB should be >=4 hours AND <= 24 hours
Someone suggested this but it's not working.
select * from tableName where
date <= DATEADD([hour], -4, CURRENT_TIME) and
date date >= DATEADD([hour], -24, CURRENT_TIME)
But it's not working. It's giving following error.
SQL0104N An unexpected token "[hour]" was found following "ortdate <=
DATEADD(". Expected tokens may include: "<func_arg_list>". SQLSTATE=42601
select *
from table t
where t.tscolumn between current timestamp - 24 hours
and current timestamp - 4 hours
Use just Hour instead of [hour]
select * from tableName where
date <= DATEADD(Hour, -4, CURRENT_TIME) and
date date >= DATEADD(Hour, -24, CURRENT_TIME)
DB2 doesn't like square brackets around name - that is a MS SQL Server mannerism.
The only reference to DATEADD() in the DB2 9.7 Info Centre (oh, beg its pardon: Center - one day, American's will learn to spell correctly) is in 'All of the following expressions are in the package com.ibm.alphablox.bloxbuilder.lib.expression', which is puzzling. I suspect the search is erroneous - though going to the SQL Manual and finding the functions listed there, DATEADD is conspicuously absent, so maybe it isn't.
So, you are going to have to manual bash for the DB2 syntax. But, if anything is going to work, it is likely to involve:
DATEADD(HOUR, -4, CURRENT_TIME)
rather than any square brackets. However, a somewhat more extensive search, including the RedBook on DB2 and Oracle Compatibility, does not show DATEADD as a function that is supported by DB2. So, the DATEADD route is doomed to ... have problems.
Since DB2 (still) doesn't have a proper (SQL standard) INTERVAL type, you are into investigating 'durations'. See DevX for an explanation - but beware the number of cookies the site '.qnsr.com' wants to set. And read the manuals at the DB2 Info Centre.
Related
So, I have two columns which are in unix/ epoch format (in milliseconds). I convert them accordingly:
dateadd(S, TIME_START/1000, '1970-01-01') AS J_Start,
dateadd(S, TIME_END/1000, '1970-01-01') AS J_End,
I want another column with the differential. However, when I try and do J_Start - J_End, I get an invalid identifier error. Is there any way around this? I've also tried substracting the full conversion syntax from one another but to no avail...
I was thinking of creating a virtual table and then joining it to the original but I would still encounter the aforementioned problem: Generating a virtual column from other, pre-existing one(s)
It works for me:
select 5 as a, 1 as b, a-b as c;
+---+---+---+
| A | B | C |
|---+---+---|
| 5 | 1 | 4 |
+---+---+---+
Unless I did not fully understand the question.
If you have your full query with exact error message, it can help.
UPDATE:
Problem in your query is that you quoted "J_Start" and "J_End", but you did not quote them in the alias of DATEADD function. If you do not quote them, Snowflake will default all identifiers to be using all UPPER case, but if you quote them, they will be preserved. So J_Start actually equals to J_START, while "J_Start" will remain as J_Start.
So your query should be:
SELECT
MOTORCYLE_REG,
STATE,
NON_MAINLAND_FLAG,
dateadd(S, TIME_START_EPOCH/1000, '1970-01-01') AS J_Start ,
dateadd(S, TIME_END/1000, '1970-01-01') AS J_End,
J_End::date - J_Start::date as J_Diff_in_dates
If you want to find out differences in seconds or milliseconds, you can use datediff or timestampdiff instead.
You can use datediff to get the differential. I am calculating the diff in days but you can change it as desired. Double quotes wasn't the cause of the error, but you don't really need them. Just use column names that don't collide with reserved keywords.
select datediff(day, dateadd(S, time_start/1000, '1970-01-01'),dateadd(S, time_end/1000, '1970-01-01'))
You could also use simple subtraction, but you'd have to cast the output of dateadd as date first. Note that you can only calculate diff in days with this method. The one above is easier to maintain, and modify for hours, minutes, and other intervals.
select dateadd(S, time_end/1000, '1970-01-01')::date - dateadd(S, time_start/1000, '1970-01-01')::date
And if you really want to re-use column alias in the same select, which I am not a fan of, you can do
select dateadd(S, time_start/1000, '1970-01-01')::date as j_start,
dateadd(S, time_end/1000, '1970-01-01')::date as j_end,
j_end-j_start as diff_days
Having said that, if you only need the diff between two dates expressed in milliseconds, it doesn't matter if you use 1970 or 1800. Just do
select floor((time_end-time_start) / (1000 * 60 * 60 * 24)) as diff_days
in snowflake you can reference the named object of the SELECT section in the other sections, and the parse most "gets what you mean", thus in snowflake:
SELECT
'2021-12-16' AS date_string,
to_date(date_string) as datetime_a,
dateadd('day', 1, date_time_a) AS a_day_later,
date_diff('hours', datetime_a, a_day_later);
is just fine, and will give the results of:
"2021-12-16", 2021-12-16, 2021-12-17, 24
thus in the SQL I gave you on your location question, I was refering to things just declared.
The error you are seeing is the fact the subtraction of date's is not supported, because what format do you want the answer in? Thus the use of date_diff
We can use existing column aliases and build some calculations .Below is example using your var's:
select
to_timestamp('2021-01-01T00:00:00')::timestamp as "J_Start" ,to_timestamp('2021-02-01T00:00:00')::timestamp as "J_end",
date_part(epoch_second, "J_Start") as "Epcoh_JSTART",
date_part(epoch_second, "J_end") as "Epcoh_JEND",
"Epcoh_JSTART" - "Epcoh_JEND";
I am making a modification to an Oracle Query, where I need to get the information found from the query date and minute up to 30 minutes ago.
For example, I made the query at 16:35, so I need it to show me the information found from 16:05 to 16:35.
I did something like this, but I don't have the result I need.
Also, how can I make it find everything loaded with current date? This is what I have done with no result
AND FV.FEC_CAR = dateadd(minute,-30,getdate()) ORDER BY F.N_FILE DESC
Thank you very much in advance
dateadd and getdate aren't valid in Oracle's SQL dialect. That looks like SQL Server syntax but it probably works in some other database as well.
In Oracle, you'd do
fv.fec_car > sysdate - interval '30' minute
or
fv.fec_car > sysdate - 30/24/60
I find the interval syntax far clearer personally
As far as I can understand and interpret, you need to see the data at a point in the past before applying some modification to your table. This case,
SELECT *
FROM tab AS OF TIMESTAMP SYSTIMESTAMP - INTERVAL '30' MINUTE
might be used to see the values of half an hour before modification if undo_retention parameter's value of your database is big enough(without forgetting that it does not guarantee to return a result even if the value is big enough)
i'm stuck with this part of the query, where I need to get only just month and year from my table.
To put in context, i have tried with "TRUNC_DATE", and Oracle give me back an error like
ORA-00904: "DATE_TRUNC": invalid identifier sql
This piece of query get it from Udacity, but in sql Developer looks like it doesn't work.
When I try search deeper, I find something like convert(char(7), ia.invoice_date(), 120) yearMonth, It still not working and an error came back. ORA-00936: missing expression
I tried a lot of ways but no solutions.
If anyones have an idea o something that could help, I will be grateful.
Here below I paste the fragment of the query for guide help:
SELECT
COUNT(ia.invoice_id) total_de_facturas,
SUM(ia.invoice_amount) monto_total,
convert(char(7), ia.invoice_date(), 120) yearMonth
FROM AP.ap_invoices_all ia
GROUP BY ia.vendor_id;
You ae mixing Oracle syntax with Postgres (date_trunc()) and SQL Server (convert()). Many date functions are vendor-specific, so you learn the relevant syntax for your database.
In Oracle, you would use trunc() to truncate a date to the first day of the month:
trunc(ia.invoice_date, 'mm')
Use the EXTRACT function, try these out to test how it works and use it in your query -
SELECT EXTRACT(YEAR FROM DATE '2020-03-07') FROM DUAL;
SELECT EXTRACT(MONTH FROM DATE '2020-03-07') FROM DUAL;
If you want a string value in YYYY-MM format - which seems to be your intention from the 120 style and the char(7) in the SQL Server-syntax convert() call - then you can just use to_char() with that format model:
to_char(ia.invoice_date, 'YYYY-MM') as yearMonth
You don't need to truncate to the first of the month as you're discarding the day part anyway.
How to get the current system time only in SQL Server / any database.
The date is not required...only the current time is required.
You can use getdate() or current_timestamp
This will give you both date and time but then you can format it however you need.
If you are using SQL Server 2008+ you can even format the result as time:
select cast(getdate() as time)
If you are not in SQL Server 2008+, then you can use many different methods to get the time only including:
SELECT convert(char(8), getdate(), 108)
See SQL fiddle demo with several versions
Using `getdate()` like:
select getdate()
=============================
and get only time use convert function with 108 code like :
select convert(varchar,GETDATE(),108)
select CONVERT(VARCHAR(8),GETDATE(),108) CurrTime;
There is 3 different statement available to get the current system time
select CONVERT(VARCHAR(8),getDate(),108)
select CONVERT(VARCHAR(8),{fn NOW()},108)
select CONVERT(VARCHAR(8),CURRENT_TIMESTAMP,108)
They all produce the same results and performance are the same, therefore it is really whatever one of the three you prefer the look of.
I tried to use
SELECT * from Results
WHERE DATEDIFF(d,Date,getdate())<30
But it seem having error with this.
For each record submitted will only display 30 days. May I know if my syntax is correct?
Greatly Appreciated,
Stan
Syntax looks OK, but you might need to 'quote' Date:
SELECT * from Results WHERE DATEDIFF(d, [Date], getdate()) < 30
Do you have a column called Date in Results?
BTW, that won't be able to use an index, whereas this will:
SELECT * from Results WHERE [Date] >= DATEADD(d, -30, getdate())
First off, you (and most of the replies in this thread) are mixing up SQL variants. You said nothing in your question about SQL Server, yet, you're getting recommendations on using SQL Server syntax (i.e., GetDate()).
The answer from JohnFx provides you correct Jet SQL syntax:
SELECT *
FROM results
WHERE ([Date] between DateAdd("d", -30, Date()) and Date())
But he is also correct that naming a field "Date" is really bad in Access/Jet. The WHERE clause might be improved with:
WHERE (results.Date between DateAdd("d", -30, Date()) and Date())
but I can't say for sure -- I would never name a field "Date" so would never encounter this kind of problem.
But there may be a simpler version, given that Jet stores its dates in a format where the integer part indicates the date and the decimal part the time. Because of that, when dealing with dates (as opposed to weeks or months or quarters), you can perform date math on them directly:
WHERE results.Date BETWEEN results.Date-30 AND Date()
This will give you exactly the same results as JohnFx's DateDiff() version, but won't need to call the DateAdd function for each row.
The key thing is using the proper syntax for a Jet database, and that means that the first argument for DateAdd() is a string value ("d") and that you can't use a SQL Server function (GetDate()), but must instead use Jet's function for the same purpose (Date()). But it's also a good idea to avoid using Jet/Access functions in your SQL when you don't have to, and that's why I believe that the "results.Date-30" version is going to be better than the DateAdd() version.
Aside: I really wish that those who post answers involving SQL would pay close attention to what database engine the questioner is using to execute the SQL. A lot of wrong answers are found in this thread precisely because those posters did not read the question carefully (it was pretty clear from the keywords what database engine was involved).
Try this:
SELECT *
FROM results
WHERE ([Date] between DateAdd("d", -30, Date()) and Date())
One other heads-up. Naming a field "Date" in Access is generally a bad idea. It is a reserved word and you will have to use brackets [] around it in all of your queries.
If you are using a Microsoft Access database, the function to get the current date is Date() rather than getdate() (that's for SQL Server).
Your query looks sound. What is the error that you're running in to?
You did not specify SQL Server as your db. In Access, the syntax for DateAdd is: DateAdd("d", 1, "31-Jan-95").