Getting wrong month - sql

SELECT TOP 1000 [pk_Id]
,[fk_resumeID]
,[fk_LoginID]
,[fk_CompanyId]
,Convert(nvarchar(11),ViewDate,105)
FROM [RecruitingDB].[Recruiting].[tbl_ViewResumeStatus]
where Convert(nvarchar(10),ViewDate,106)
between Convert(nvarchar(10),'17-10-2015',106) and Convert(nvarchar(10),'23-10-2015',106)
I am using this above sql for getting only Oct. Record but I am getting Sept. record.
Have you any idea why this is happening.

You are comparing the alphabetic values. You should avoid that, when dealing with numeric or date values.
Example 17-10-2015 would unintentionally be between 16-01-2015 and 18-01-2015
Use this instead:
SELECT TOP 1000 [pk_Id]
,[fk_resumeID]
,[fk_LoginID]
,[fk_CompanyId]
,Convert(char(10),ViewDate,105)
FROM [RecruitingDB].[Recruiting].[tbl_ViewResumeStatus]
WHERE
ViewDate > '2015-10-17' and
ViewDate < dateadd(d, 1, '2015-10-23')
If ViewDate is a date, you can replace the WHERE clause with this:
WHERE
ViewDate BETWEEN '2015-10-17' and '2015-10-23'

Well it will do if you convert your dates to strings. Your query is looking for anything alphabetically between'17-10-2015' and '23-10-2015'. So for example that would include '18-09-2015'.

Don't do date arithmetic using strings. If for some reason you have to, then use YYYY-MM-DD formats:
SELECT TOP 1000 [pk_Id], [fk_resumeID], [fk_LoginID], [fk_CompanyId],
Convert(nvarchar(11),ViewDate,105)
FROM [RecruitingDB].[Recruiting].[tbl_ViewResumeStatus]
WHERE ViewDate >= '2015-10-17' AND ViewDate < '2015-10-24';
Also, note the use of the comparisons. BETWEEN can be dangerous, because the column could have a time component. This method works regardless of whether or not the column has a time component. And, it will take advantage of an index on ViewDate.
The following is also acceptable in SQL Server:
SELECT TOP 1000 [pk_Id], [fk_resumeID], [fk_LoginID], [fk_CompanyId],
Convert(nvarchar(11),ViewDate,105)
FROM [RecruitingDB].[Recruiting].[tbl_ViewResumeStatus]
WHERE CAST(ViewDate as date) BETWEEN '2015-10-17' AND '2015-10-23';
The conversion to date remove the time component. And, the function call is sargable, meaning that the query can still use an index on ViewDate.

Related

How can I generate a random timestamp appended to getdate() in SQL Server?

The following sql select generates the current date and time:
select
Getdate() AS DueDate
which looks like:
2021-02-06 10:16:35.340
I'd like to use getdate() (or an equivalent alternative) to continue getting the current date but I'd like to randomize the time component. I am having trouble finding a workable solution within a select statement.
Any suggestions?
here is another way if you need to have random time for each row:
SELECT
DATEADD(SECOND ,RAND(CHECKSUM(NEWID())) * 86400,CONVERT(datetime,CONVERT(varchar(8),GETDATE(),112)))
FROM tablename
You can simply add another DATEADD around your expression. For example, using INFORMATION_SCHEMA:
SELECT DATEADD(MILLISECOND, RAND(ROW_NUMBER()OVER(ORDER BY C.ORDINAL_POSITION)) * 10000000, GETDATE())
FROM INFORMATION_SCHEMA.COLUMNS AS C
You can play around with the RAND() and ROW_NUMBER() functions to get the result you want. If you have a primary key with lots of gaps, that helps to randomize.

Why do I get a conversion failed error when I use my attribute on my WHERE clause but it works when I don't?

Why is my query returning a result when I run the following query:
SELECT MAX(CAST(IssueDate as Date))
FROM (SELECT IssueDate
FROM [Transient].[Commissions_TIB]
WHERE ISDATE(issuedate) = 1
GROUP BY IssueDate) t
But when I use the 'IssueDate' attribute in my WHERE clause it fails to convert to a date from a string?
SELECT MAX(CAST(IssueDate as Date))
FROM (SELECT IssueDate
FROM [Transient].[Commissions_TIB]
WHERE ISDATE(issuedate) = 1
GROUP BY IssueDate) t
WHERE CAST(IssueDate as Date) <= CAST(GETDATE() as date)
Most likely, there are IssueDates in your table that are not valid. For some reason, SQL Server seems to decide to apply the outer predicate before the inner predicate. I suspect that it relates to a query planner optimization technique called predicate pushdown - and, here, this might be considered a bug...
In a nutshell: don't use isdate(). It is not safe anyway, as it relies on some complicated (and undisclosed) heuristic. Instead, use try_convert() or try_cast(), which check and convert at once.
Your whole query can be simplified as:
SELECT MAX(TRY_CAST(IssueDate as Date))
FROM [Transient].[Commissions_TIB]
WHERE TRY_CAST(IssueDate as Date) <= CAST(GETDATE() as date)
Because ISDATE() is a terrible function. ISDATE(20200101), for example returns 1, but both CONVERT(datetime, 20200101) and CONVERT(date,20200101) returns different errors.
If you need to check is something is valid for another data type, use TRY_CONVERT: WHERE TRY_CONVERT(date,issuedate) IS NOT NULL
Of course, the real problem is your design. Don't store dates in a data type that isn't a date and time data type. Fix your design and this problem can't happen.

Date is string between hyphens in SQL Server

I have date formats that are as follows:
Date_str
19-12-2007
31-7-2009
3-1-2010
31-11-2009
etc.
I can't do the following:
CONCAT(RIGHT(Date_str,4),SUBSTRING(Date_str,3,3),LEFT(2))
because as you can see above, the dates are not the same length. Is there a way in SQL Server to extract the date as datetime/date?
I also tried
Convert(datetime, Date_str)
but it just threw an error:
The conversion of a varchar data type to a datetime data type resulted
in an out-of-range value.
If 2012+, I would use Try_Convert(). This will return bogus dates as NULL.
Example
Declare #YourTable Table ([Date_str] varchar(50))
Insert Into #YourTable Values
('19-12-2007')
,('31-7-2009')
,('3-1-2010')
,('31-11-2009')
Select *
,try_convert(date,Date_Str,105)
from #YourTable
Returns
Date_str (No column name)
19-12-2007 2007-12-19
31-7-2009 2009-07-31
3-1-2010 2010-01-03
31-11-2009 NULL -- Notice 11/31 is NOT a date
See https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql for date formats
You probably need
CONVERT(DateTime, Date_str, 105)
As I mentioned in the comments, the only realistic solution is to convert that string into a proper date-typed column. The current format doesn't allow date sorting, or search for a range of dates, eg to find entries in the last week, or between one date and the other.
Parsing with CONVERT or TRY_PARSE means that no indexes can be used to speed up queries. Each time :
WHERE CONVERT(Date, Date_str, 105) > '20170101'
is used, the server will have to scan the entire table to convert the data, then filter the rows.
If you can't change the type of the field itself, you can create a persisted computed column that returns the value as a date and add indexes to it. You'll be able to use that column for indexed querying:
alter table SomeTable add date2 as TRY_convert(Actual_Date,date_str,105) PERSISTED
create index IX_SomeTable_ActualDate on SomeTable (Actual_Date)
This will allow you to perform sorting without tricks:
SELECT *
FROM SomeTable
ORDER BY Actual_Date
Or run range queries that take advantage of the IX_SomeTable_ActualDate index:
SELECT *
FROM SomeTable
Where Actual_Date Between DATEADD(d,-7,GETDATE()) AND GETDATE()
If you have 1000 rows, you could get 1000 times better performance.
Existing applications won't even notice the change. Newer queries and applications will be able to take advantage of indexing and sorting
I had a similar problem: my column (<my_date_field>) had date values in the form of
2021-01
2021-02
2021-10
2021-12
and so on, with data type of nvarchar(4000), and I always ran into the Conversion failed when converting date and/or time from character string. error (when trying e.g. CAST(<my_date_field> AS DATE) or CAST(CAST(<my_date_field> AS VARCHAR(7)) AS DATE) etc.)
I was able to convert them to date with the following code:
SELECT
CONVERT(date, <my_date_field> + '-01') AS first_day_of_month
FROM my_table
which resulted in
2021-08-01
2021-07-01
2021-06-01
2021-05-01

Informix SQL Compare DateTime value on Where Statement

I have a datetime field called entrytimestamp, with content of the field is for example: 2014-01-07 16:20:00. I would like to query all the data that has entrytimestamp after 09:00:00 o'clock, regardless what date it was.
I have a prototype query:
select *
from trading
where to_char(entrytimestamp, "%H%M%S") >= "090000"
But I think it is logically a mistake, because it will compare the text string, not the sequence value. What is the right way to do it?
Use the EXTEND() function to extract the time part:
select *
from mytable
where extend(entrytimestamp, hour to second) > '09:00:00'
I dont know if it performs well,
but you could compare directly with the time portion of the datetime,
i think a cast here should perform pretty fast (just cuts off the date)
select *
from (select getdate() as mydatetime) as data
where cast(mydatetime as time) > cast('09:00:00' as time)
EDIT, just noticed this was for Informix SQL, so not sure it works then, Sorry

SQL statement between date

This is driving me crazy and not sure what I'm missing here..
so here is my data column looks like:
StartDateTime:
---------------
2012-01-17 11:13:46.530
2012-01-17 11:17:22.530
2012-02-17 11:31:22.223
here is my query trying to get:
select * from tablName
where convert(varchar(10), startDateTime, 101) between '2012-01-17' and '2012-01-17'
based on the above I should be getting TWO rows? but it does not, it return zero rows. what will be the correct way of doing?
PS:
I've looked at the MSDN site too:
Your query would only match dates that are between 2012-01-17 00:00:00 and 2012-01-17 00:00:00. So, the only matches would be when the date is exactly 2012-01-17 00:00:00.
Instead, I would do this:
declare #dateInput as DateTime
set #dateInput = '2012-01-17'
select *
from tablName
where startDateTime >= #dateInput
and startDateTime < dateadd(day, 1, #dateInput)
Note: SQL Server 2008+ has a new data type Date with no time component that can make these types of queries more readable.
There is now more information so I'll add a more appropriate answer.
The requirements are now a stored procedure passed a Date type parameter, not DateTime, and the desire is to return rows from a table based on criterion against a DateTime field named StartDateTime...
create procedure dbo.spGetEntriesForOneDay
#DesiredDate DateTime
as
SET NOCOUNT ON;
SET #DesiredDate = DATEADD(day, DATEDIFF(day, 0, #DesiredDate), 0)
SELECT Field1, Field2 -- see note 1
FROM dbo.TableName
WHERE StartDateTime >= #DesiredDate -- see note 2
AND StartDateTime < DATEADD(day, 1, #DesiredDate) -- see note 3
NOTE 1: Don't use * in production code, especially in a stored procedure. Besides being wasteful by returning columns you probably don't need and precluding the optimization of a covering index on a subset of the columns required you would need to recompile this stored procedure whenever the underlying table is altered in order to avoid unpredictable results.
NOTE 2: Avoid wrapping fields in functions. A field not wrapped in a function can potentially be matched by the optimizer to an index while a field wrapped in a function never will.
NOTE 3: #Martin Smith and #RedFilter are correct in that .997 precision assumes DateTime datatype forever; this approach is more future proof because is makes no assumptions of data type precision.
You're using a datetime field (I'm guessing).
Don't forget the time:
select * from tablName
where startDateTime between '2012-01-17' and '2012-01-17 23:59:59.997'
You can use the DateDiff function in the where clause. It would look like this:
select col1, col2 from tablName where DateDiff(day, startDateTime, #DesiredDate) = 0