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

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))

Related

How does one find rows created today if the CreatedDate column is of type datetimeoffset?

I have a column named CreatedDate of type DateTimeOffset, and I need to query to see rows created today. If this column was of type DateTime I would do this:
SELECT *
FROM MyTable
WHERE CreatedDate >= GETDATE()
How does one accomplish this with a DateTimeOffset column, however?
Environment: SQL Server 2014
Take a look at the TODATETIMEOFFSET function that is built into SQL Server.
Here is an example of how it is used (-5 is my timezone offset...your usage may vary)...again, this also considers you are only worried about >= current time as your original question suggested. You would need to adjust usage of GETDATE() if you care about the entire day (see comment on original question).
select * from TestingDates d where d.CreatedDate >= TODATETIMEOFFSET(GETDATE(), '-05:00')

Convert to mm/dd/yyyy and select max value

Using SQL Server 2014, I have a date field named LAST_BASELINE_UPDATE_DATE that is stored as datetime.
I used the CONVERT function to convert to mm/dd/yyyy:
convert(date,LAST_BASELINE_UPDATE_DATE,101) as BASELINE_UPDATE_DATE
What I want to be able to do is then select the MAX value of BASELINE_UPDATE_DATE without creating a table. Is this even possible?
It's a little unclear from your post what your data is and what you're trying to get out. Here are a couple solutions, hopefully one of which is applicable
Assuming you want your result as a string formatted mm/dd/yyyy you can do this
select convert(varchar(10), max(LAST_BASELINE_UPDATE_DATE), 101))
from YourTable
If you just need it as a date, just do
select max(LAST_BASELINE_UPDATE_DATE)
from YourTable
if LAST_BASELINE_UPDATE_DATE is already a string (formatted mm/dd/yyyy) and you want it as a date,
select max(convert(date, LAST_BASELINE_UPDATE_DATE, 101))
from YourTable
I think you are complicating this. Just do the conversion on the max datetime values.
declare #table table (LAST_BASELINE_UPDATE_DATE datetime)
insert into #table
values
('20160701 12:21'),
('20160705 03:21'),
('20160401 19:21'),
('20161201 04:21')
select
convert(varchar(10),max(LAST_BASELINE_UPDATE_DATE),101)
from
#table
This method converts your single returned row, which is the max() value of your datetime columns, as opposed to converting every row and then finding the max value.

Cast select column to date in view to then run query against

I have a view where I Select about 100 rows to allow users to easily query data. In this data, I have a field that is sometimes a date and sometimes text. A date or text depends on type. I cast to a date value like so.
SELECT Cast(Value as Date) as column
from Table
Where type = 1
When you then try to run a query against this column, you get a Conversion failed when converting date and/or time from character string. Here is the query.
SELECT Column
From View
WHERE Column BETWEEN '01/01/2015' AND '12/31/2015'
I have another field that is a date and if I replace it in this query, the query works. Likewise the data from the whole table will load. Any ideas are appreciated. Thanks
Basically, I need this Query to work and not give me the error described above.
select cast(value as date)
from Value
where type = 1
and cast(value as date) between '01/01/2015' and '12/31/2015'
My guess is that you have entries in that column that cannot be converted to datetime. You may be able to find them by running
Select * from table where isdate(value) = 0

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]
)

Proper way to index date & time columns

I have a table with the following structure:
CREATE TABLE MyTable (
ID int identity,
Whatever varchar(100),
MyTime time(2) NOT NULL,
MyDate date NOT NULL,
MyDateTime AS (DATEADD(DAY, DATEDIFF(DAY, '19000101', [MyDate]),
CAST([MyDate] AS DATETIME2(2))))
)
The computed column adds date and time into a single datetime2 field.
Most queries against the table have one or more of the following clauses:
... WHERE MyDate < #filter1 and MyDate > #filter2
... ORDER BY MyDate, MyTime
... ORDER BY MyDateTime
In a nutshell, date is usually used for filtering, and full datetime is used for sorting.
Now for questions:
What is the best way to set indices on those 3 date-time columns? 2 separate on date and time or maybe 1 on date and 1 on composite datetime, or something else? Quite a lot of inserts and updates occur on this table, and I'd like to avoid over-indexing.
As I wrote this question, I noticed the long and kind of ugly computed column definition. I picked it up from somewhere a while ago and forgot to investigate if there's a simpler way of doing it. Is there any easier way of combining a date and time2 into a datetime2? Simple addition does not work, and I'm not sure if I should avoid casting to varchar, combining and casting back.
Unfortunately, you didn't mention what version of SQL Server you're using ....
But if you're on SQL Server 2008 or newer, you should turn this around:
your table should have
MyDateTime DATETIME
and then define the "only date" column as
MyDate AS CAST(MyDateTime AS DATE) PERSISTED
Since you make it persisted, it's stored along side the table data (and now calculated every time you query it), and you can easily index it now.
Same applies to the MyTime column.
Having date and time in two separate columns may seem peculiar but if you have queries that use only the date (and/or especially only the time part), I think it's a valid decision. You can create an index on date only or on time or on (date, whatever), etc.
What I don't understand is why you also have the computed datetime column as well. There s no reason to store this value, too. It can easily be calculated when needed.
And if you need to order by datetime, you can use ORDER BY MyDate, MyTime. With an index on (MyDate, MyTime) this should be ok. Range datetime queries would also be using that index.
The answer isn't in your indexing, it's in your querying.
A single DateTime field should be used, or even SmallDateTime if that provides the range of dates and time resolution required by your application.
Index that column, then use queries like this:
SELECT * FROM MyTable WHERE
MyDate >= #startfilterdate
AND MyDate < DATEADD(d, 1, #endfilterdate);
By using < on the end filter, it only includes results from sometime before midnight of that date, which is the day after the user-selected "end date". This is simpler and more accurate than adding 23:59:59, especially since stored times can include microseconds between 23:59:59 and 00:00:00.
Using persisted columns and indexes on them is a waste of server resources.

Resources