How to select a row based on a timestamp in Snowflake SQL - snowflake-cloud-data-platform

I am struggling to retrieve a particular row based on its exact timestamp.
CREATE TABLE PUBLIC.ERIC( SOME_ROW_ID INTEGER NOT NULL
, MY_TIMESTAMP TIMESTAMP_NTZ NOT NULL DEFAULT CAST(CURRENT_TIMESTAMP() AS TIMESTAMP_NTZ(9))
);
I insert a row in there
INSERT INTO PUBLIC.ERIC(SOME_ROW_ID) VALUES(1);
I retrieve it...
SELECT * FROM PUBLIC.ERIC;
This returns a value like this: "2020-04-07 09:58:51"
Now, if I try to retrieve that row, I keep missing it
SELECT *
FROM PUBLIC.ERIC
WHERE MY_TIMESTAMP = CAST('2020-04-07 09:58:51' AS TIMESTAMP_NTZ(9));
How am I supposed to retrieve that row?
I suppose I am getting mixed up in the timestamp thing (or precision)...
Any help greatly appreciated!

timestamp_ntz(9) has nanosecond precision, so your where clause needs to also have nanosecond precision (e.g. 2020-04-07 10:34:04.426)

Related

SQL Server changes the value in the float column when converting to varchar

I have a column in my table that is of float type. The table was automatically generated when I imported the spreadsheet (Excel) data to my database. Thus there is a column I wish to change from float to varchar, but when I try to do this, I get an error:
'tblInvoices' table
Unable to create index 'IX_tblInvoices'.
The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'dbo.tblInvoices' and the index name 'IX_tblInvoices'.
The duplicate key value is (1.00001e+006). The statement has been terminated.
It is a unique column, and set that way (not set as the primary key for reasons). I have already run queries to search for and delete duplicate fields but there are none. The query I ran as follows:
WITH CTE AS
(
SELECT
Invoice,
RN = ROW_NUMBER()OVER(PARTITION BY Invoice ORDER BY Invoice)
FROM
dbo.tblInvoices
)
DELETE FROM CTE
WHERE RN > 1
So the value within the Invoice column is 1000010 and when I run the following query a single row is found.
SELECT *
FROM [TradeReceivables_APR_IFRS9].[dbo].[tblInvoices]
WHERE Invoice = 1.00001e+006
Note that I have searched for the value in the error, 1.00001e+006, and not 1000010.
So my question is why does the DBMS do this? Why does it change the value like that? When I remove the column, it does it with another column and so on and so on (about 40 000 rows in total). How can I change the column from float to varchar without changing the data and getting errors?
Any help will be greatly appreciated!
It seems that the field is an integer so you can Cast it to BIGINT before cast to VARCHAR
Declare #Invoice as float = 1.00001e+006
print cast(#Invoice as varchar) -->> Result : 1.00001e+006
print cast(cast(#Invoice as bigint) as varchar) -->> Result : 1000010

Is there a way to get CURRENT_TIMESTAMP to only store date, hours and minutes in a database?

I'm storing data in PostgreSQL with one column set to a default CURRENT_TIMESTAMP. I'm trying to get this default to only store: date, hours and minutes. Does anyone know how I can do it?
I need to be able to manipulate the data using Ruby to then display it on an html page. At the moment I can display a timestamp like this: 2019-09-15 12:50:05.745811 but would like something more like this: 2019-09-15 12:50.
At the moment I'm extracting each row of a table into a Ruby object and defining each value as accessible instance variable so #id = id, #content = content and #timestamp = timestamp. I would like a way to either edit a string like this: 2019-09-15 12:50:05.745811 in ruby or what I guess might be easier to find a way for the DEFAULT CURRENT_TIMESTAMP to only store the relevant data. Any help, much appreciated.
This is how my table has been created:
CREATE TABLE my_table (
id SERIAL PRIMARY KEY,
content VARCHAR(280),
timestamp timestamp DEFAULT CURRENT_TIMESTAMP
);
If you always want your date resolution only to the second then you can specify that in the definition:
CREATE TABLE my_table (
id SERIAL PRIMARY KEY,
content VARCHAR(280),
timestamp timestamp(0) DEFAULT CURRENT_TIMESTAMP
);
If you want the capability to process and/or display fractional seconds then make the conversion when selecting:
Select ..., timestamp::timestamp(0) ...
When you want to show less the second precision then you must use to_char(...) and specify the mask for what you want, So in your example 2019-09-15 12:50:
select ... to_char(timestamp, 'yyyy-mm-dd hh24:mi:'), ...
IMHO it is very bad practice to name a column the same as a data type. It will at sometime cause confusion or mistakes.
Use to_char() to remove everything after the minutes and to_timestamp() to convert back to timestamp:
CREATE TABLE my_table (
id SERIAL PRIMARY KEY,
content VARCHAR(280),
timestamp timestamp DEFAULT to_timestamp(to_char(current_timestamp, 'YYYY-MM-DD HH24:MI'), 'YYYY-MM-DD HH24:MI')
);
See the demo.

How to Split the String and integer in Sql to find the max and put it in SP or functions to call

I have a Retailer code ,It is combination of varchar and Int =>RT003880 like this
I have create a Retailer code as script-wise every day. So i need the last Retailer code i have inserted.
So I have split the Integer and varchar for finding the Max value.
This is the max value by using Query.
select SUBSTRING(Retailer_code,5,9) as RetailerCode
Into #maxfindtable
from dbo.sample
select MAX(RetailerCode) from #maxfindtable
I need to put in in function or Stored Procedure how to do this
Try:
select max(SUBSTRING(RetailerCode,3,len(RetailerCode)-2))
for RT003880 the integer part is starting from position 3,and
len(RetailerCode)-2 isdefine the length of the substring. i.e: all the
character starting from 3rd position
See SUBSTRING for more clearification.
EDIT 2:
try Using Cast
create table #tab (genId varchar(max))
insert into #tab(genId)
values('RT00031'),('RT00013232'),('RT00034'),('RT00084')
select * from #tab
select max(cast(SUBSTRING(genId,3,len(genId)-2) as int)) from #tab
I'd split the RetailerCode into two columns (one CHAR/VARCHAR and one INT/SMALLINT/NUMERIC) to be able to get some performance out of the table. Possibly use a calculated column to concatenate them if requested. I would never query on the calculated column if it was not persisted, however.
Today I have inserted 10000 new records,its choosing wrong max value. Both The codes Written Same Value,Maximum Value is RT0017898,But It shows RT0009999.
After I have Checked a sample data
RetailerId RetailerCode RetailerName
1 RT00031 mBigBazar
2 RT00034 TBazar
3 RT00084 SaravanaStore It shows Correct Value - 00084
When I have insert a new Record it shows wrongly
RetailerId RetailerCode RetailerName
1 RT00031 mBigBazar
2 RT00034 TBazar
3 RT00084 SaravanaStore
4 RT00013232 NewStore
Now it shows 00084 .why it shows wrong?

T-SQL Select where Subselect or Default

I have a SELECT that retrieves ROWS comparing a DATETIME field to the highest available value of another TABLE.
The Two Tables have the following structure
DeletedRecords
- Id (Guid)
- RecordId (Guid)
- TableName (varchar)
- DeletionDate (datetime)
And Another table which keep track of synchronizations using the following structure
SynchronizationLog
- Id (Guid)
- SynchronizationDate (datetime)
In order to get all the RECORDS that have been deleted since the last synchronization, I run the following SELECT:
SELECT
[Id],[RecordId],[TableName],[DeletionDate]
FROM
[DeletedRecords]
WHERE
[TableName] = '[dbo].[Person]'
AND [DeletionDate] >
(SELECT TOP 1 [SynchronizationDate]
FROM [dbo].[SynchronizationLog]
ORDER BY [SynchronizationDate] DESC)
The problem occurs if I do not have synchronizations available yet, the T-SQL SELECT does not return any row while it should returns all the rows cause there are no synchronization records available.
Is there a T-SQL function like COALESCE that I can use with DateTime?
Your subquery should look like something like this:
SELECT COALESCE(MAX([SynchronizationDate]), '0001-01-01')
FROM [dbo].[SynchronizationLog]
It says: Get the last date, but if there is no record (or all values are NULL), then use the '0001-01-01' date as start date.
NOTE '0001-01-01' is for DATETIME2, if you are using the old DATETIME data type, it should be '1753-01-01'.
Also please note (from https://msdn.microsoft.com/en-us/library/ms187819(v=sql.100).aspx)
Use the time, date, datetime2 and datetimeoffset data types for new work. These types align with the SQL Standard. They are more portable. time, datetime2 and datetimeoffset provide more seconds precision. datetimeoffset provides time zone support for globally deployed applications.
EDIT
An alternative solution is to use NOT EXISTS (you have to test it if its performance is better or not):
SELECT
[Id],[RecordId],[TableName],[DeletionDate]
FROM
[DeletedRecords] DR
WHERE
[TableName] = '[dbo].[Person]'
AND NOT EXISTS (
SELECT 1
FROM [dbo].[SynchronizationLog] SL
WHERE DR.[DeletionDate] <= SL.[SynchronizationDate]
)

How to generate timestamp value for binary(8) field?

I need two timestamp fields in my table. One, of the timestamp type for update operation, and the one (binary(8)) for the insert one.
The timestamp type's value is auto generated by the sql server,
Where to get the value for that second column from?
I'm not sure to understand your problem but :
SELECT CONVERT(varbinary(8), CAST(CONVERT(DATETIME, GETDATE()) AS TIMESTAMP))

Resources