Compare some date predicate based on 1st of the month - date

I would like to get DATE format like in the title (yyyy-mm) from getdate() , in order to use it in where clause to get < and > dates from the one i formatted .So far i found almost everybody uses convert(varchar(10),getdate(),120) but that's varchar and it cant be check with < and > right ? So can someone help me to make a Date in format yyyy-mm or it's impossible ?

Why can't VARCHAR be compared using > and < operators? So long as you have a character string in an appropriate format, you can compare it just fine. For instance, CONVERT(VARCHAR(10), GETDATE(), 120) returns an ODBC Canonical format date, as "YYYY-MM-DD". This can obviously be compared using > and < to obtain correct results.
However, you would generally not want to do this in a database. Predicate such as this:
WHERE CONVERT(VARCHAR(10), [DateColumn], 120) >= '2018-02-26'
are considered "non-SARGable", and cannot use an index. This means that the server will apply brute force conversions to the underlying columns prior to the comparison, resulting in Index Scans or Table Scans, depending upon your schema.
For the vast majority of situations, you want the column to be used as an operand without any kind of conversion beforehand. Thus, the predicate should be expressed as:
WHERE [DateColumn] >= '2018-02-26'
This will result in an implicit cast of the '2018-02-26' operand into Date or DateTime (whatever the column type is), and this can use an index.
The absolute best would be an explicit cast such as this:
WHERE [DateColumn] >= CAST('2018-02-26' AS DATETIME)
This way, there is no room for mistakes, implicit conversions, or non-SARGable predicates.

Put simply, you do not want to do this in the way you are asking.
To look for records that match a specific year and month, simply use two where criteria in this manner:
declare #SomeDate date = '20180114'; -- This is any date.
-- This gets the first day of the month of the date above.
declare #MonthStart date = dateadd(month,datediff(month,0,#SomeDate),0);
-- This gets the first day of the following month of the date above.
declare #NextMonthStart date = dateadd(month,datediff(month,0,#SomeDate)+1,0);
select cols
from tables
where DateCol >= #MonthStart
and DateCol < #NextMonthStart;

if you have an existing datetime you should compare it against another time, using between for example. Why do you want to do a string comparison

Related

Cast varchar as date select distinct top 100

I am trying to fix a query that has come to light in SSRS after the new year. We have an input that comes from another application. It grabs a date and stores it as varchar. The SSRS report then fetches the top 100 'dates' but when 2017 dates have come around, this are not in the top 100.
The existing query is as follows
SELECT DISTINCT TOP (100)
FROM DenverTempData
ORDER by BY Date DESC
The date is stored as VARCHAR. So obviously this query doesn't grab a value such as 01012017 as being a top 100 (over values likes 12312016). I thought maybe I can simply change the datatype on this column to datetime. But the information comes from a flat file and is converted, so it's a little more difficult that that. So I'm hoping to do a select of the distinct top 100 while converting the date column to datetime or just date and grabbing the last 100 dates.
Can someone help with the query syntax? I'm thinking a cast to convert varchar to date, but how do I format with distinct top 100? I'm simply looking to retrieve the last 100 dates in chronological order from a column that is stored as varchar but contains a string representing a date.
Hopefully that makes sense
It is always a bad idea to store a date as string. This is highly culture specific!
You can cast your formatted string-date to a real date like this:
DECLARE #DateMMDDYYYY VARCHAR(100)='12312016';
SELECT CONVERT(DATE,STUFF(STUFF(#DateMMDDYYYY,5,0,'-'),3,0,'-'),110)
After the conversion your sorting (and therefore the TOP 100) should work as expected.
My strong advise: Try to store your dates in a column of a real date type to avoid such hassel!
SELECT DISTINCT TOP 100 (CAST(VarcharColumn as Date) as DateColumn)
FROM TABLE
Order by DateColumn desc

Converting string timestamp into date

I have dates in a postgres database. The problem is they are stored in a string field and have values similar to: "1187222400000" (which would correspond to 07.08.2007).
I would like to convert them into readable dates usind some SQL to_date() expression or something similar but can't come up with the correct syntax to make it work.
There really isn't enough information here for a conclusion, so I propose this 'scientific-wild-ass-guess' to resolve your puzzle. :)
It appears this number is UNIX 'epoch time' in milliseconds. I'll show this example as if your string field had the arbitrary name, 'epoch_milli'. In postgresql you can convert it to a time stamp using this statement:
SELECT TIMESTAMP WITH TIME ZONE 'epoch' + epoch_milli * INTERVAL '1 millisecond';
or using this built-in postgresql function:
SELECT to_timestamp(epoch_milli / 1000)
either of which, for the example '1187222400000', produces the result
"2007-08-15 17:00:00-07"
You can do some of your own sleuthing with quite a few values selected similarly to this:
SELECT to_timestamp(epoch_milli/1000)::DATE
FROM (VALUES (1187222400000),(1194122400000)) AS val(epoch_milli);
"Well, bollocks, man. I just want the date." Point taken.
Simply cast the timestamp to a date to discard the excess bits:
SELECT to_timestamp(epoch_milli / 1000)::DATE
Of course its possible that this value is a conversion or is relative to some other value, hence the request for a second example data point.

Is ISO8601 the best date-format for PostgreSQL jsonb when i want to filter by the date?

I'm new to PostgreSQL and I have the following question:
I have a table with just an id-column and a data-column, which uses the jsonb-type. Inside the jsonb-object I have a datetime field. I read in various posts, that I should use the ISO-8601 dateformat to store in the DB.
I want to filter my table by date like this:
SELECT * FROM table WHERE data->'date' > '2016-01-01T00:00'
Is this really the best date-format for this purpose?
Thanks in advance :)
IMHO Your query should produce
ERROR: operator does not exist: jsonb > timestamp with time zone
If I get it right. In case you change -> to ->> it should get a text value instead of jsonb field (which is also not comparable to timestamp).
It should be smth like
SELECT * FROM table WHERE (data->>'date')::timestamptz > '2016-01-01T00:00' to work
The big advantage of that format is that string order corresponds to date order, so a comparison like the one you quote in your question would actually work as intended.
A second advantage is that a timestamp in that format can easily be converted to a PostgreSQL timestamp with time zone value, because the type input function understands this format.
I hope you are not dealing with dates “before Christ”, because it wouldn't work so easily with those.

TSQL Between 2 dates or >= and <=?

Morning experts. I have a very simple query that I can not seem to get working as it should.
I have a table that has invoiceNumber, CustNum, Datetime, and Grand_total
I want to pull all transactions between a set of dates in this example all transactions between 4/10/2014 and 4/23/2014. I was using:
SELECT Invoice_number
,CustNum
,DATETIME
,Grand_Total
FROM invoice_totals
WHERE custnum = '10014877'
AND DATETIME BETWEEN '2014-04-10'
AND '2014-04-23'
ORDER BY DATETIME DESC
I just realized if there are any dates on 4/23 that this does not show them.. I have tried to substuite using:
WHERE custnum = '10014877'
AND DATETIME >= '2014-04-10' AND DATETIME <='2014-04-23'
But it is still giving me the same results (ignoring any transactions that occured on 4/23)
the last record pulling up has a datetime stamp of 2014-04-22 12:26:08.000. There ARE 2 transactions on the 23'ed I am trying to include.
Thank you very much.
The part:
AND DATETIME <='2014-04-23'
is actually(according to TSQL):
AND DATETIME <='2014-04-23 00:00:000'
So you're quering from midnight and missing all the transactions from 00:01 to 23:59 on the 23rd.
Try:
AND DATETIME <='2014-04-23 23:59:999'
Or
AND DATETIME < '2014-04-24'
Both should include all the transactions for the day of the 23rd.
If you're working with continuous data, such as datetimes, it's usually better to switch to using a semi-open interval - an inclusive start date and an exclusive end date. Exclusive end dates are usually easier to calculate:
WHERE custnum = '10014877'
AND DATETIME >= '20140410' AND DATETIME <'20140424'
I've also switched to a safe, unambiguous date format.
The alternative, using <= or BETWEEN (which is just shorthand for a pair of >= and <= comparisons, so your two queries were identical) requires an inclusive end date. Which depending on the exact data type you're using may be 2014-04-23T23:59:59.997 or 2014-04-23T23:59:59.9999 or any number of other possibilities - if you get it wrong and overspecify the value, it'll get rounded to be 20140424 and then an inclusive comparison is incorrect.
And even if you get it right today, it's a pain to find all usage of this pattern if the data type of the column changes later.
BETWEEN is inclusive with respect to the boundaries.
However, I'm guessing that the type of your (poorly named) DATETIME field is .. DATETIME, so in the comparison, the date '2014-04-23' gets converted to a DATETIME as follows: '2014-04-23:00:000'. Thus, all records with DATETIME greater than that first moment on 04-23 are rejected.

Comparing two time columns in ASP.NET

I'm rather new to ASP.NET and SQL, so I'm having a tough time trying to figure out how to compare two time columns. I have a timestamped column and then a Now() column in an .mdb database. I need to have a gridview display records that are "Greater than or equal to 3 hours" from the timestamp. Any idea how I can accomplish this?
The Transact-SQL timestamp data type is a binary data type with no time-related values.
So to answer your question: Is there a way to get DateTime value from timestamp type column?
The answer is: No
You need another column of datetime2 type and use > operator to for comparison. You might want to set default value of getutcdate() to set it when each row is inserted.
UPDATE:
Since the column is of datetime type and not timestamp type (there is a type in SQL Server called timestamp, hence the confusion) you can just do
WHERE [TimeCalled] <= DATEADD(hour, -3, GETDATE())
Make sure your server is running in the same timezone as your code. It may be safer to store all dates in UTC. In that case use GETUTCDATE instead on GETDATE
Timestamps are generally used to track changes to records, and are updated every time the record is changed. If you want to store a specific value you should use a datetime field.
If you're using a DateTime Column and you want the result in TSQL try
DATEDIFF(Hour, 'Your DateTime Column here', 'pass Now() here' )
try to execute this example in TSQL:
select DATEDIFF(Hour, '2012-11-10 00:00:59.900', '2012-11-10 05:01:00.100')