BigQuery #run_date used as different types - google-bigquery

I have a scheduled query using the #run_date parameter in BigQuery.
SELECT
#run_date AS run_date,
timestamp,
event
FROM
`ops-data.usage.full_user_dataset`
WHERE
DATE(timestamp) < #run_date
timestamp is of type TIMESTAMP
I am unable to schedule it - the schedule option is greyed out in the new UI and unavailable in the classic UI (it says it requires valid SQL). If I try and run the query then I receive error message Undeclared parameter 'run_date' is used assuming different types (DATE vs INT64) at [2:3]
After trying various things I was able to schedule the query below. The idea was to force BigQuery to treat #run_date as a date without changing it
SELECT
DATE_SUB(#run_date, INTERVAL 0 DAY) AS run_date,
timestamp,
event
FROM
`ops-data.usage.full_user_dataset`
WHERE
DATE(timestamp) < #run_date
Why does this error occur and why does the fix work?

I think it is a bug around #run_date, below workaround should work for you until it is fixed.
DECLARE run_date DATE DEFAULT #run_date;
SELECT
run_date,
timestamp,
event
FROM
`ops-data.usage.full_user_dataset`
WHERE
DATE(timestamp) < run_date
BTW, since the workaround utilizes Scripting and not being able to set a destination table, if you do need a destination table, it has to be written as:
CREATE OR REPLACE TABLE <yourDestinationTable>
AS SELECT ... -- your query

Related

How to calculate a date difference in Google Cloud SQL?

I'm trying to generate a query that will display the date difference between a date stored in a column and the current date, but i'm getting the error:
"Cannot call method "getTime" of null."
What function can I use to calculate this date difference in Google Cloud SQL?
Current code:
SELECT date, DATEDIFF(date, CURRENT_DATE()) AS daysLeft
FROM table;
Are you using a mysql instance on Google Cloud. If so try the following
SELECT date, DATEDIFF(date, CURDATE()) AS daysLeft
FROM table;
All that changed is CURDATE() instead of CURRENT_DATE()
Turns out, the error was in another part of the code. The originally posted SQL query works perfectly fine, the problem was the model was casting the result as a date variable instead of an int.
The DATEDIFF function requires three parameters.
SELECT date, DATEDIFF(day, date, CURRENT_DATE()) AS daysLeft
FROM table;
This should return your result in days left.

Azure stream analytics query - how to set even timestamp based on a javascript udf function?

I am timestamping data stream input events by a property "TS" in the message. However before I timestamp it using TS, I want to ensure that TS is ISO8601 compliant. If TS is not ISO8601 ocmpliant, I want to use EventEnqueuedUtcTime which is the arrival time of the message as timestamp.
My query looks something like this
SELECT
T.*
FROM
input TIMESTAMP BY PARTITION BY PartitionId TIMESTAMP BY udf.getEventTimestamp(T)
Here udf.getEventTimestamp(T) returns the TS property in message(T) if it is ISO8601-compliant otherwise it will return EventEnqueuedUtcTime( arrival time of message in Iot Hub).
Running this script locally gives me the exception -
Error : Unexpected hosted function call
I also tried to use CASE construct to accomplish this
SELECT
T.*
FROM
input TIMESTAMP BY PARTITION BY PartitionId TIMESTAMP BY
CASE
WHEN udf.isValid(T.TS) THEN T.TS
ELSE T.EventEnqueuedUtcTime
END
where udf.isValid(T.TS) returns true if the property TS is a valid ISO8601 compliant timestamp.
Again running this locally returns - Error : Unexpected hosted function call
As per Microsoft Azure docs, After you add a JavaScript user-defined function to a job, you can use the function anywhere in the query, like a built-in scalar function
Does this mean that we cannot use udfs in TIMESTAMP BY and CASE constructs?
Can you suggest any workaround?
At this time we can't use UDF within the TIMESTAMP BY clause.
However we case use TRY_CAST to solve your requirement.
Here's the query with the workaround:
SELECT
T.*
FROM
input PARTITION BY PartitionId TIMESTAMP BY
CASE
WHEN TRY_CAST(T.TS AS DateTime) is not null THEN T.TS
ELSE T.EventEnqueuedUtcTime
END
Let me know if you have any further question.
Thanks,
JS

How to translate this SQL query to tableau?

I have a SQL query which shows time activity of each account. Database is Microsoft SQL Server on Windows Server 2008.
Help me please to translate this query to tableau with using parameters Parameters.Date1 and Parameters.Date2 instead of #time.
The result of the query:
USER,Date,Total time
USER1,2016-09-22,07:00:00.0000000
USER2,2016-09-22,08:00:00.0000000
USER3,2016-09-22,05:00:00.0000000
SQL query:
DECLARE #time datetime
set #time = '08.09.2016'
SELECT
[User],
CAST(DATEADD(SECOND, sum(datediff(DAY, #time, [Start])), #time) AS date) 'Date',
CAST(DATEADD(SECOND, sum(datediff(SECOND, '00:00:00',[Period])), '00:00:00') AS time) 'Total time'
FROM
[User].[dbo].[UserAction]
WHERE
[Start] >= #time+'00:00:00' and [Start] <= #time+'23:59:59'
GROUP BY
[USER]
input data to build the query:
USER, Start,End,Period
USER1,2016-09-22 09:00:00.000,2016-09-22 12:00:00.000,03:00:00
USER1,2016-09-22 12:00:00.000,2016-09-22 13:00:00.000,01:00:00
USER1,2016-09-22,13:00:00.000,2016-09-22 16:00:00.000,03:00:00
USER2,2016-09-22,09:00:00.000,2016-09-22 13:00:00.000,04:00:00
USER2,2016-09-22,13:00:00.000,2016-09-22 17:00:00.000,04:00:00
USER3,2016-09-22,09:00:00.000,2016-09-22 10:00:00.000,01:00:00
USER3,2016-09-22,10:00:00.000,2016-09-22 12:00:00.000,02:00:00
USER3,2016-09-22,12:00:00.000,2016-09-22 14:00:00.000,02:00:00
I don't have enough imaginary stack overflow points yet to make a comment instead of an answer, but I would agree with Gordon Linoff.
A table valued function in sql can be used directly in a Tableau data source, and it's treated just like a table.
Note I did not test the below, but here is what the equivalent function might look like:
CREATE FUNCTION dbo.MyFuntion (#time datetime)
RETURNS TABLE
AS
RETURN
(
SELECT
[User]
,cast(DATEADD(SECOND, sum(datediff(DAY, #time,[Start])),#time) as date)'Date'
,cast(DATEADD(SECOND, sum(datediff(SECOND, '00:00:00',[Period])),'00:00:00') as time)'Total time'
FROM
[User].[dbo].[UserAction]
WHERE
[Start] >= #time+'00:00:00' and [Start] <= #time+'23:59:59'
GROUP BY [USER]
);
Tableau 9 (haven't tried 10) seems to discourage custom SQL (it warns anyone that opens your workbook) and stored procedures (slow vs. same sql in a function).
Alternatively, adding the pure dbo.UserAction table to a data source and making calculated fields for the second two columns might work: Tableau Documentation. It seems to have all the functions needed to manipulate dates. However, there may be some crazy limitation associated with parameters that might limit it, honestly can't remember off the top of my head.
You don't need custom SQL for this. Keep it simple. Connect Tableau directly to your UserAction table.
You can either:
Put Day(Start) on the filter shelf, Make sure it is a continuous Date truncated to the Day. Show the filter and set the filter to let you pick a single value at a time - I would choose a slider UI.
Or write a calculated field to put on the filters shelf that references a parameter such as day(Start) = day(Date1)
Put User on one shelf, such as rows, and Sum(Period) on another such as columns. That should do it unless Tableau has trouble interpreting your Period field datatype. If so, try changing the datatype to Number inside Tableau to see if it converts durations to numbers automatically, if not you may need to write a calculated field for the conversion.

Sql Query using 'Like' is giving results but using '=' does not returns any result in Oracle

The Query using LIKE :(This query when fired gives the desired result)
select * from catissue_audit_event where event_timestamp like '16-DEC-14'
But when using query with '=' results in an empty resultset
select * from catissue_audit_event where event_timestamp='16-DEC-14'
Here event_timestamp is of type Date
Strange thing is that the query runs for other dates such as:
select * from catissue_audit_event where event_timestamp='15-DEC-14'
What can be the issue? I already checked for leading and trailing spaces in the data
Output after running the first query:
In Oracle a DATE (and of course a TIMESTAMP) column contains a time part as well.
Just because your SQL client is hiding the time, doesn't mean it isn't there.
If you want all rows from a specific day (ignoring the time) you need to use trunc()
select *
from catissue_audit_event
where trunc(event_timestamp) = DATE '2014-12-16';
Be aware that this query will not use an index on the event_timestamp column.
You should also not rely on implicit data type conversion as you do with the expression event_timestamp = '16-DEC-14. That statement is going to fail if I run it from my computer because of different NLS settings. Always use a proper DATE literal (as I have done in my statement). If you don't like the unambiguous ISO date, then use to_date():
where trunc(event_timestamp) = to_date('16-12-2014', 'dd-mm-yyyy');
You should avoid using month names unless you know that all environments (which includes computers and SQL clients) where your SQL statement is executed are using the same NLS settings. If you are sure, you can use e.g. to_date('16-DEC-14', 'dd-mon-yy')
The reason why this is different is different to the solution to your issue.
The solution to your issue is to stop performing date comparisons by implicit conversion to a string. Convert your string to a date to perform a date comparison:
select * from catissue_audit_event where event_timestamp = date '2014-12-16'
I cannot stress this enough; when performing a date comparison only compare dates.
Your column EVENT_TIMESTAMP is being implicitly (this is bad) converted to a date in accordance with your NLS_DATE_FORMAT, which you can find as follows:
select * from nls_session_parameters
This governs how date-data is displayed and implicitly converted. The reason why LIKE works and and = doesn't is because your NLS_DATE_FORMAT is masking additional data. In other words, your date has a time component.
If you run the following and then re-select the data from your table you'll see the additional time component
alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss'
Thus, if you want all the data for a specific date without constraint on time you'll need to remove the time component:
select * from catissue_audit_event where trunc(event_timestamp) = date '2014-12-16'
have you tried matching the event_timestamp format example: DD-MMM-YY with the date that you are passing?

HSQL Get Date and Time from TIMESTAMP

I have a HSQLDB table with some informations and where a timestamp is stored
I want to select informations from specific time periods like every information of october between 0am and 5pm.
I didn't found any function like mysql'ones DATE(myfield) OR TIME(myfield) which would be perfect for what i want.
SELECT * FROM myTable
WHERE DATE(myField) BETWEEN '2012-10-01' AND '2012-10-30'
AND TIME(myField) BETWEEN '00:00:00' AND '17:00:00'
The only things i found are to use the functions YEAR(), DAYOFMONTH(), DAYOFYEAR(), HOUR() ANd MINUTE() but I was wondering if there aren't any other simpler solutions.
There is no need for such specialised functions as HSQLDB supports the general CAST expression for this purpose
CAST(myField AS DATE)
CAST(myField AS TIME)
HSQLDB also supports automatic cast from DATE to TIMESTAMP. Therefore an optimised query that can use an index on the myField column should look like this:
SELECT * FROM myTable
WHERE myField BETWEEN DATE'2012-10-01' AND DATE'2012-10-30'
AND CAST(myField AS TIME) BETWEEN TIME'00:00:00' AND TIME'17:00:00'