To convert date in Snowflake - date

I am trying to work with the date (timestamp to be precise) and getting into trouble. My requirement is below.
I have a stage table where the data is stored as JSON in a Variant Column and the data looks like below in that column.
{
“message_body”: {
“campus_code”: “TEST”,
“campus_name”: “TEST”,
“event_type”: “TEST”,
“location_code”: “A00000”,
“location_name”: “TEST”,
“order”: {
“credit_total”: 0,
“app_version”: “1.0.9”,
“asap”: 1,
“order_datetime”: “2021-01-08 18:19:34”
}
“timezone_offset_minutes”: -360,
}
}
I have below requirements.
Convert the Datetime into only date, so i tried the below and its failing
select TO_TIMESTAMP((body:message_body:order:order_datetime), ‘yyyy-mm-dd HH24:MI:SS’)
FROM “stage_table”
. its failing with below error message
SQL compilation error: error line 1 at position 7 too many arguments for function [TO_TIMESTAMP(GET(GET(GET(stage_table.BODY, ‘message_body’), ‘order’), ‘order_datetime’), ‘yyyy-mm-dd HH24:MI:SS’)] expected 1, got 2
I have to subtract the minutes from order_datetime. I have to subtract timezone_offset_minutes from
order_datetime
select datetime, dateadd(minute, -300, body:message_body:order:complete_datetime)
FROM
“stage_table”
. its failing with below error message
Timestamp ‘’ is not recognized
Any quick help is hugely appreciated.
Thanks

This will work if you cast the extracted order_datetime to string with ::string:
with sample_table as (
select parse_json(replace(replace('{
“message_body”: {
“campus_code”: “TEST”,
“campus_name”: “TEST”,
“event_type”: “TEST”,
“location_code”: “A00000”,
“location_name”: “TEST”,
“order”: {
“credit_total”: 0,
“app_version”: “1.0.9”,
“asap”: 1,
“order_datetime”: “2021-01-08 18:19:34”
}
,
“timezone_offset_minutes”: -360,
}
}', '“', '"'), '”', '"')) body
)
select TO_TIMESTAMP(body:message_body:order:order_datetime::string, 'yyyy-mm-dd HH24:MI:SS')
from sample_table
-- 2021-01-08T18:19:34Z

Related

prisma $queryRaw doesn't work with single quotes in the string

i have a query that goes
select count(id), status, "createdAt"::date from "ProjectLog" where "projectId" = (select id from "Project" where slug = ${id}) and "createdAt" > current_date - interval '${interval} day' group by "createdAt"::date, status;
i've also tried user Prisma.sql to pass the value inside the quotes but it keeps throwing error that it expected 1 argument but fount 2.
i did not have this issue with prisma 2.20.1
this issue is only happening on version 3.3.0
Query: select count(id) as count, status, "createdAt"::date from "ProjectLog" where "projectId" = (select id from "Project" where slug = $1) and "createdAt" > current_date - interval '$2 day' and key notnull group by "createdAt"::date, status
Param: ["main","30"]
PrismaClientKnownRequestError:
Invalid `prisma.queryRaw()` invocation:
Your raw query had an incorrect number of parameters. Expected: `1`, actual: `2`.
code: 'P1016',
clientVersion: '3.3.0',
meta: { expected: 1, actual: 2 }
}
any suggestions ?
i'm not sure if this is a bug.
didn't find an elegant solution in the prism documentation, I couldn't even find one, but there is a way that works...you can try this ${'variable'}
Try to use:
const interval = num + ' days';
${interval}::TEXT::INTERVAL
instead of interval '${interval} day'
This is work for me!

case when in where clause postresql

select service_code,service_cat_code,mobile_no,upper(applicant_name_eng) as name,to_char(license_date,'dd/mm/yyyy')as license_from,to_char(license_valid_upto,'dd/mm/yyyy')as license_to,Upper(license_no),district_code,taluk_code,CONCAT(address_building,', ', address_cityvillage,', ',address_locality,', ',address_landmark,', ',address_street) as address
from mst_license
WHERE cast(license_valid_upto as date) = case
WHEN license_valid_upto < now()
THEN
case
when license_valid_upto = '2021-06-30'
then 1 else 0
END
ELSE
case when license_valid_upto > now()
then 1 else 0
End
END
and Upper(license_no)='1SP146924BJP'
I want license valid should be either greater than now or if license valid less than now it must be with the date ''30/06/2021' but when i use above query i get error
ERROR: operator does not exist: date = integer
LINE 3: WHERE cast(license_valid_upto as date) = case
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
SQL state: 42883
Character: 418
Help me out guys
The main issue you have is that your case statement returns an integer (1 or 0) but you are trying to compare that to a date, which you cannot do as Postgres is a strict data typing. Even if it did work it would always be false (well except for 1969-12-31/1970-01-01). Moreover the case structure is not needed. The best/correct to compare dates is just use date values. Since you did not indicate the data type for column license_valid_upto so based on how it is used I'll assume it is timestamp with timezone as that is what NOW() returns. Your query becomes:
select service_code
, service_cat_code
, mobile_no
, upper(applicant_name_eng) as name
, to_char(license_date,'dd/mm/yyyy')as license_from
, to_char(license_valid_upto,'dd/mm/yyyy')as license_to
, upper(license_no) as license_no
, district_code
, taluk_code
, concat(address_building,', '
,address_cityvillage,', '
,address_locality,', '
,address_landmark,', '
,address_street) as address
from mst_license
where and upper(license_no)='1SP146924BJP'
and ( cast(license_valid_upto as date) > cast( now() as date)
or (cast (icense_valid_upto as date) < cast( now() as date)
and cast (icense_valid_upto as date) = date '2021-06-30'
)
);
Also, learn for format your queries for readability and so you do not need to scroll right. You, and others looking at your queries later will appreciate it later.

Postgresql: HAVING statement that skips rows which are null or empty?

Is there any way to skip rows that are null or empty? I could use some help with sorting the output of a subtable. My having statement is returning an error I can’t fix.
It returns the error: ERROR: invalid input syntax for integer: " "
This seems to be because some rows in my table will have either null values or be empty and the having statement is getting hung up there.
Here is the full query
SELECT
count(job),
year,
zipcode
FROM
(
SELECT
substring (cast(dobjobs.prefilingdate AS varchar), '^\d\d\d\d') AS year,
dobjobs.job,
dobjobs.bbl,
pluto_17v1.zipcode
FROM
dobjobs
JOIN pluto_17v1 ON dobjobs.bbl = pluto_17v1.bbl
GROUP BY
dobjobs.prefilingdate,
dobjobs.bbl,
pluto_17v1.zipcode,
dobjobs.job
ORDER BY
year
) AS sub
GROUP BY
year, zipcode
HAVING
CAST( zipcode AS int ) IN (10039, 10039, 10026, 10030, 10037, 10027, 10032, 10033, 10040, 10034, 10031)
ORDER BY
year;

T-SQL - Creating Graph from data in View

I'm fairly new to T-SQL, Stored Procedures and Microsoft SQL Server Management Studio.
I have created a View in my database called BodyBasics. In this View, there is a column called BackAngle. In the BackAngle column, I list at which angle the users back is bent. The datatype is float and can range from 90 to 180.
Some example values found in this View column are:
173,10786534157, 147,423570266, 170,196359990068, 148,774131860277, 153,439316876929, 147,063469480619, 173,861485242977, 172,1319088368, 145,416983331938, 163,02645970309, 147,65814822779, 146,212510299859, 173,769456580658
The View looks like this:
| ID | Timestamp | RecordingId | BodyNumber | BackAngle |
What I would like to do is SELECT the BackAngle data from the View in chronological order and plot the data into a graph.
The query I have tried is:
GO
DECLARE #BackAngle TABLE(Backangle FLOAT);
INSERT #BackAngle(Backangle) SELECT dbo.ViewBodies.BackAngle FROM dbo.ViewBodies
WHERE dbo.ViewBodies.BackAngle IS NOT NULL
ORDER BY Timestamp;
SELECT geometry::STGeomFromText( 'LINESTRING(' + #BackAngle(Backangle) + ')' );
GO
The errors that I get from this code is:
Msg 102, Level 15, State 1, Line 7
Incorrect syntax near 'Backangle'.
Msg 102, Level 15, State 1, Line 9
Incorrect syntax near '('.
I got the geometry::STGeomFromText syntax from this article:
http://sqlmag.com/t-sql/generating-charts-and-drawings-sql-server-management-studio
Can someone point out what is wrong with my code and whether this is the right way to do this? Is there any alternative?
You don't need a temp table you should make a TEXT STRING with variables to use it in LINESTRING. As a scale line you can use row numbers (1,2,3,4,...)
DECLARE #WKT AS VARCHAR(8000);
SET #WKT =
STUFF(
(SELECT ','
+ CAST( ROW_NUMBER()
OVER (ORDER BY [timestamp]) AS VARCHAR(100))
+ ' ' + CAST( BackAngle AS VARCHAR(30) )
FROM ViewBodies
WHERE BackAngle IS NOT NULL
ORDER BY [timestamp]
FOR XML PATH('')), 1, 1, '');
SELECT geometry::STGeomFromText( 'LINESTRING(' + #WKT + ')', 0 );

Convert a string representing a timestamp to an actual timestamp in PostgreSQL?

In PostgreSQL: I convert string to timestamp with to_timestamp():
select * from ms_secondaryhealthcarearea
where to_timestamp((COALESCE(update_datetime, '19900101010101'),'YYYYMMDDHH24MISS')
> to_timestamp('20121128191843','YYYYMMDDHH24MISS')
But I get this error:
ERROR: syntax error at end of input
LINE 1: ...H24MISS') >to_timestamp('20121128191843','YYYYMMDDHH24MISS')
^
********** Error **********
ERROR: syntax error at end of input
SQL state: 42601
Character: 176
Why? How to convert a string to timestamp?
One too many opening brackets. Try this:
select *
from ms_secondaryhealthcarearea
where to_timestamp(COALESCE(update_datetime, '19900101010101'),'YYYYMMDDHH24MISS') >to_timestamp('20121128191843','YYYYMMDDHH24MISS')
You had two opening brackets at to_timestamp:
where to_timestamp((COA.. -- <-- the second one is not needed!
#ppeterka has pointed out the syntax error.
The more pressing question is: Why store timestamp data as string to begin with? If your circumstances allow, consider converting the column to its proper type:
ALTER TABLE ms_secondaryhealthcarearea
ALTER COLUMN update_datetime TYPE timestamp
USING to_timestamp(update_datetime,'YYYYMMDDHH24MISS');
Or use timestamptz - depending on your requirements.
Another way to convert a string to a timestamp type of PostgreSql is the above,
SELECT to_timestamp('23-11-1986 06:30:00', 'DD-MM-YYYY hh24:mi:ss')::timestamp without time zone;
I had the same requirement as how I read the title. How to convert an epoch timestamp as text to a real timestamp. In my case I extracted one from a json object. So I ended up with a timestamp as text with milliseconds
'1528446110978' (GMT: Friday, June 8, 2018 8:21:50.978 AM)
This is what I tried. Just the latter (ts_ok_with_ms) is exactly right.
SELECT
data->>'expiration' AS expiration,
pg_typeof(data->>'expiration'),
-- to_timestamp(data->>'expiration'), < ERROR: function to_timestamp(text) does not exist
to_timestamp(
(data->>'expiration')::int8
) AS ts_wrong,
to_timestamp(
LEFT(
data->>'expiration',
10
)::int8
) AS ts_ok,
to_timestamp(
LEFT(
data->>'expiration',
10
)::int8
) + (
CASE
WHEN LENGTH(data->>'expiration') = 13
THEN RIGHT(data->>'expiration', 3) ELSE '0'
END||' ms')::interval AS ts_ok_with_ms
FROM (
SELECT '{"expiration": 1528446110978}'::json AS data
) dummy
This is the (transposed) record that is returned:
expiration 1528446110978
pg_typeof text
ts_wrong 50404-07-12 12:09:37.999872+00
ts_ok 2018-06-08 08:21:50+00
ts_ok_with_ms 2018-06-08 08:21:50.978+00
I'm sure I overlooked a simpler version of how to get from a timestamp string in a json object to a real timestamp with ms (ts_ok_with_ms), but I hope this helps nonetheless.
Update: Here's a function for your convenience.
CREATE OR REPLACE FUNCTION data.timestamp_from_text(ts text)
RETURNS timestamptz
LANGUAGE SQL AS
$$
SELECT to_timestamp(LEFT(ts, 10)::int8) +
(
CASE
WHEN LENGTH(ts) = 13
THEN RIGHT(ts, 3) ELSE '0'
END||' ms'
)::interval
$$;