Using DateDiff() to find the difference between getDate() and a concatonated value - sql

I am trying to find the difference between today's date and a value that is a concatenation of mulitple values but begins with an 8 digit date without any dashes or forward slashes. There's something wrong with my syntax I believe, but I'm not yet skilled enough to see what I'm doing incorrectly. Here is what I have so far:
select DateDiff(dd, (select MIN(CAST(Left(batchid, 8) as Date)) from
[Table]), getdate()) from [Table]
This is returning the following error: "Msg 241, Level 16, State 1, Line 1
Conversion failed when converting date and/or time from character string."

I think your have data where the left 8 is not a valid date in yyyymmdd format. Your can run the following query to find them
select batchid, isdate(Left(batchid, 8))
from [Table]
where isdate(Left(date, 8)) = 0
This is the correct syntax to your query. Your original example had an extra parenthesis which I assume was a typo since your error appears to be data related.
select
datediff(dd, (select min(cast(left(batchid, 8) as date))
from [Table]), getdate())

Could you provide some more details.
Namely, what does batchid look like in 8 digit form? is it YYYYMMDD or DDMMYYYY or MMDDYYYY?
Also could you show us the result of the following?
select MIN(CAST(Left(batchid, 8) as Date)))
from [Table])
Sry for using an answer, i don't have the rep to add a comment directly below.

This was may error. I was working with another table and forgot batchID was not the same for both. The concatenated batchID in the table I posted a question about can't be converted to a date.

Related

How to get start and end of month in numeric type for SQL where clause

I want to run a query monthly to look for records from the previous month. The where clause will be greater or equal to the 1st day of the month and less or equal to the last day. The difficultly I am having is the dates are stored as numbers in a column with a numeric data type. The format being used is yyyymmdd. We are currently manually changing the where clause, so e.g. show me any records with dates >=20201001 to <=20201031, but we need to automate this process. I have tried a few ways to try and solve this but need some guidance.
So far I've tried:
select concat( CONCAT(cast((Year(DATEADD(month, -1, getdate()))) as numeric),cast((Month(DATEADD(month, -1, getdate()))) as numeric)),'01')
Returns error message operand data type numeric is invalid for concat operator. Works in separate query window returning format yyyymmdd.
SELECT DATEADD(mm, DATEDIFF(mm, 0, (DATEADD(month, -1, getdate()))), 0)
Returns error message arithmetic overflow error converting expression to data type date time. Works partly in separate query window but returns yyyy-mm-dd hh:mi:ss:ms
Any help would be greatly appreciated.
Thanks
The real solution is fix the design; don't store dates in a datatype other than a date and time data type.
What you can do, however, is convert the value of GETDATE() to a numerical value of the same format:
SELECT ...
FROM ...
WHERE NumericalDate >= CONVERT(varchar(8),DATEADD(DAY, 1, EOMONTH(GETDATE(),-1)),112)
AND NumericalDate < CONVERT(varchar(8),DATEADD(DAY, 1, EOMONTH(GETDATE())),112)
For today, this would return rows where NumericalDate is in November 2020 (specifically on or after 20201101 and before but not on 20201201).
Note, I don't "bother" to CAST/CONVERT the varchar to a Numerical data type, as it'll be implicit cast due to data type precedence.
You can use artihmetics like so:
where dates >= year(getdate()) * 10000 + month(getdate()) * 100 + 1
and dates < year(dateadd(month, 1, getdate())) * 10000 + month(dateadd(month, 1, getdate())) * 100 + 1
Compare the month and forget the days.
BETWEEN 20201000 and 20201099 finds the same rows as your example >=20201001 to <=20201031
That means that you do not have to figure out how many days are in the month.

show data with shipmentdate bigger than today

i am trying to pulling data for all shipments with shipmentdate greater than todays date. However, I cant figure out an easy conversion of the format of the nvarchar, i get a out of range value error when trying to run this:
select *
from dbo.BAS_CT_RAW_ARCHIVE_TBL
where SHIPMENTDATE > GETDATE()
Msg 242, Level 16, State 3, Line 1 The conversion of a nvarchar data
type to a datetime data type resulted in an out-of-range value.
Try:
select *
from dbo.BAS_CT_RAW_ARCHIVE_TBL
where convert(date, SHIPMENTDATE, 103) > GETDATE()
To see how to use convert with non-standard dates see this.
Further consideration: use proper datatypes for columns, i.e. don't store dates as strings, but as date datatype - it will prevent you from having such problems.
according to your data format that got from comment below should work
select * from dbo.BAS_CT_RAW_ARCHIVE_TBL
where CONVERT(date, SHIPMENTDATE, 103) > convert(date, GETDATE())

SQL Server Date time conversion giving incorrect result?

I have 6 digit value in one column that I need to convert to date-time. I tried two different formula given below.
(DATEADD(day, CONVERT(int, COLUMNNAME)-((1000*(CONVERT(int, COLUMNNAME)/100)))-1, DATEADD(year, CONVERT(int, COLUMNNAME/1000), '1 Jan 1900'))) as Order_date
But this is giving following error message:-
Adding a value to a 'datetime' column caused an overflow. [SQLSTATE=22007, SQLERRORCODE=517]
convert(datetime, (convert (int, COLUMNNAME)), 6) as Order_date
And this is giving incorrect value for date. There is one particular value 118150 that should result into 2018-05-30 :00:00:00, but my statement is returning 2223-06-27 00:00:00
Can anybody please help what is causing error with first statement and how can I modify it to run on entire table.
If I understand the date format correctly, this will work:
select dateadd(day, x % 1000 - 1, datefromparts(1900 + x / 1000, 1, 1))
from (values (118150)) v(x)

How to get year of character hijri date SQL Server

I searched and tried many examples unable to solve my hijri date is like,
19/07/1440
I tried this query
SELECT TOP 200
DATEPART(YEAR, EndDateHejri)
FROM
student
but I'm getting this error
Conversion failed when converting date and/or time from character string
I'm unable to solve error - hoping for your suggestions
I bit of Google-Fu and format 131 should help you convert Hijri dates into Gregorian Dates...
DECLARE #hijri DATETIME = CONVERT(datetime, ' 7/05/1421 12:14:35:727PM', 131)
SELECT #hijri
Unfortunately, all the date functions (DATEPART(), DATENAME(), even DATEADD(), etc) are all based on manipulating Gregorian dates. So you can't use them.
So, you're forced to use string manipulation.
DECLARE #hijri DATETIME = CONVERT(datetime, ' 7/05/1421 12:14:35:727PM', 131)
SELECT #hijri
SELECT DATEPART(year, #hijri)
-- Gives 2000 :(
SELECT RIGHT(CONVERT(VARCHAR(10), #hijri, 131), 4)
-- Gives 1421 :)
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=901209ae0cdcf38cdcdea8afad4fd034
Posting a different answer. As the OP is only after the year part, and they've stated that it's always in the format 00/00/yyyy why not just use RIGHT? So:
SELECT RIGHT(EndDateHejri,4) as HejriYear;
I tried answer #Vishnu Chandel it's working for me .
SELECT DATEPART(YEAR,CONVERT(datetime2(0),convert(VARCHAR,EndDateHejri),103))
And full code is :
SELECT TOP 200
SELECT DATEPART(YEAR,CONVERT(datetime2(0),convert(VARCHAR,EndDateHejri),103)) as year
FROM
student
Please try below code to get the correct output.
SELECT DATEPART(YEAR,CONVERT(datetime2(0),convert(VARCHAR,EndDateHejri),103));

Mistyped dates in SQL

I was wondering if there is a way to detect mistyped dates in SQL in a general sense.
For example:
Order1 - 2014
Order2 - 2104
Order3 - 2041
I am guessing a form of case statement using wildcards would do the trick. But I am kind of a beginner in that regard.
EDIT - Sorry, for clarification, my column actually contains YYYY-MM-DD. However, I am only concerned with the year formatting. The datatype is Date for TSQL.
Thank you!
Since your data is already in a date column you don't need to worry about whether the value is a valid date or not.
So basically you are looking - from what I can tell - to see if the date falls in an expected range.
So you might want to do something like
SELECT * FROM MYTABLE WHERE MYDATE NOT BETWEEN '01/01/1900' AND '12/31/2020'
(obviously you can make the range whatever values you want, either static values or values stored in an options table)
You could take this a step further and validate it on a dynamic range, something like this:
SELECT * FROM MYTABLE
WHERE MYDATE NOT BETWEEN DATEADD(YEAR, -5, GETDATE()) AND DATEADD(YEAR, 5, GETDATE())
A further step would be to validate it in a range, based on some other field in the table, such as a created-on date for the record, like this:
SELECT T.* FROM MYTABLE T
WHERE T.MYDATE NOT BETWEEN DATEADD(YEAR, -5, T.CREATEDON) AND DATEADD(YEAR, 5, T.CREATEDON)
This gives you a bit more flexibility, because the "incorrect" dates may actually be valid at another point in time.
This should give you some starting points from which you can flesh out your exact needs.
assuming you are using a varchar field (through the comments) try,
Where your_column not like '200_' or your_column not like '201_'
if you were using a int for year you could use a range
Where your_column not between 2000 and 2014