any idea why when i use this code
SELECT * FROM Runtime.dbo.AnalogHistory WHERE TagName = 'LT73011.Out_PV'
AND datediff(HOUR, DateTime, '2018-03-14 08:02:23.449') = 0
knowing that Runtime.dbo.AnalogHistory is my view
i get blank
but when i query with this
SELECT * FROM Runtime.dbo.AnalogHistory WHERE TagName = 'LT73011.Out_PV'
AND DateTime <= '2018-03-14 08:59:00.000'
i get all the values that happened at the hour 8am
is there's a curtain restriction with a view? how can i work around this?
I can't reproduce your observations/behavior, but if you want an exact way to target 8am on a certain date then try this:
SELECT *
FROM Runtime.dbo.AnalogHistory
WHERE
TagName = 'LT73011.Out_PV' AND
DateTime >= '2018-03-14 08:00:00' AND DateTime < '2018-03-14 09:00:00';
This approach also has the added advantage that an index on the DateTime column can be used (i.e. the WHERE clause is sargable).
Related
I try to get selected the current month data by using SQL Server LIKE but it not get the any result. My when I run same code in my SQL it get the original result. What is error of my query? This query I want to run in SQL Server.
SELECT EnrolledID, Date, Time
FROM dbo.view_attendance
WHERE Date LIKE '2019-08%'
ORDER BY Date,Time;
Date in the SQL Server database date is something like that 2019-08-14 00:00:00.000.
Even though you have asked for a LIKE, I would recommend using the following format:
SELECT [EnrolledID]
, [Date]
, [Time]
FROM dbo.view_attendance
WHERE [Date] >= '20190801' and [Date] < '20190901'
ORDER BY [Date], [Time];
Although there is no syntax error in the case of using LIKE over DATETIME columns, I would recommend using LIKE only when trying to parse STRING values, in search for a certain pattern.
LIKE will not work with DATETIME columns and will not return results. If your column is of type DATETIME then I recommend using the above method.
MySql does implicit conversions between data types in expressions like your case:
Date LIKE '2019-08%'
so MySql converts Date to varchar and the expression returns a valid result because both operands are treated as varchars.
You can find more here: https://dev.mysql.com/doc/refman/8.0/en/type-conversion.html
SQL Server does not do this, so you must explicitly do the conversion or use a function like:
WHERE FORMAT(Date, 'yyyy-MM') = '2019-08'
if [Date] column is DateTime Type, try this :
declare #currentMonth int = datepart(MONTH,GETDATE())
declare #currentYear int = datepart(YEAR,GETDATE())
SELECT [EnrolledID]
, [Date]
, [Time]
FROM dbo.view_attendance
WHERE DATEPART(year,[Date]) = #currentYear And DATEPART(MONTH,[Date]) = #currentMonth
ORDER BY [Date], [Time];
or this:
SELECT [EnrolledID]
, [Date]
, [Time]
FROM dbo.view_attendance
WHERE DATEPART(year,[Date]) = datepart(YEAR,GETDATE()) And DATEPART(MONTH,[Date]) = datepart(MONTH,GETDATE())
ORDER BY [Date], [Time];
I want to get date from yyyy-mm-dd to yyyy-mm-dd in SQL.
Example: I have two parameter #startdate : 2015-12-28 and #enddate : 2016-01-02, and database in SQLServer, datatype is varchar(10)
DATE_ORDER
28-12-2015
30-12-1996
29-12-2016
30-12-1997
24-12-2015
27-12-1993
03-01-2016
01-01-1992
02-01-2016
etc...
Ok,now I want to get data from #startdate : 2015-12-28 and #enddate : 2016-01-02. I use SELECT * FROM TABLE_X WHERE DATE_ORDER >= #startdate AND DATE_ORDER <= #enddate . But the results are not what I expected. Here are the results I want
28-12-2015
30-12-1996
29-12-2016
30-12-1997
01-01-1992
02-01-2016
I think to solve this problem, I need to do two things :
First, get date range from #startdate to #enddate , in here 28/12/2015, 29/12/2015, 30/12/2015, 31/12/2015, 01/01/2016, 02/01/2016.
The second: get the date in database same in range 28/12, 29/12, 30/12, 31/12, 01/01, 02/01, ignoring the year.
Can you give me some ideas about this ?
Your actual format is "105-italian" find details here.
You can convert your existing VARCHAR(10)-values with this line to real datetime
SELECT CONVERT(DATETIME,YourColumn,105)
Next thing to know is, that you should not use BETWEEN but rather >=StartDate AND < NakedDateOfTheFollowingDay to check date ranges
So to solve your need Get date-range from 2015-12-28 to 2016-01-02 you might do something like this:
DECLARE #Start DATETIME={d'2015-12-28'};
DECLARE #End DATETIME={d'2016-01-02'};
SELECT *
FROM YourTable
WHERE CONVERT(DATETIME,YourDateColumn,105)>=#Start AND CONVERT(DATETIME,YourDateColumn,105)<#End+1
Attention Be aware, that the conversion lets your expression be not sargable. No index will be used.
Better was to store your date as correctly typed data to avoid conversions...
Try this query
SET DATEFIRST 1
DECLARE #wk int SET #wk = 2
DECLARE #yr int SET #yr = 2011
--define start and end limits
DECLARE #todate datetime, #fromdate datetime
SELECT #fromdate = dateadd (week, #wk, dateadd (YEAR, #yr-1900, 0)) - 4 -
datepart(dw, dateadd (week, #wk, dateadd (YEAR, #yr-1900, 0)) - 4) + 1
SELECT #todate = #fromdate + 6
;WITH DateSequence( Date ) AS
(
SELECT #fromdate AS Date
UNION ALL
SELECT dateadd(DAY, 1, Date)
FROM DateSequence
WHERE Date < #todate
)
--select result
SELECT * FROM DateSequence OPTION (MaxRecursion 1000)
So, after the 2nd or 3rd edit, it slowly becomes clear, what you want (i hope).
So you REALLY WANT to get the dates with the year beeing ignored.
As someone pointed out already, date-values are stored internally not as string, but as internal datatype date (whatever that is in memory, i don't know).
If you want to compare DATES, you cannot do that with ignorance of any part. If you want to, you have to build a NEW date value of day and month of given row and a hard coded year (2000 or 1 or whatever) for EVERY row.
SELECT * FROM TABLE_X WHERE convert(date,'2000' + substring(convert(char(8),convert(datetime, 'DATE_ORDER', 105),112),5,4),112) >= #startdate AND convert(date,'2000' + substring(convert(char(8),convert(datetime, 'DATE_ORDER', 105),112),5,4),112) <= #enddate
If your startdate and enddate go OVER sylvester, you have to do 2 queries, on from startdate to 1231, one from 0101 to enddate.
I am running a SQL Statement, shown below. This is ultimately going to be used to populate a reporting table nightly with the days transactions. When I run it without the
Cast(M._CreateDateTime as Date) = #StartDate
It takes 1:40.
With the function back in the where clause it takes over 10 minutes.
Declare #StartDate DAte = GetDate()
If Object_ID ('tempdb.dbo.#WinBack') is not null Drop Table #WinBack
Select
M.HospitalMasterID
,M.TxnSite
,P.ClientID
,M.PatientID
,M.TxnDate as CallDate
,M.TxnCode
,M.EnteredMasterID
,U.UserName
,U.UserDept
Into
#WinBack
From
Avimark_OLTP.dbo.MedicalHistory as M
Inner JoinAvimark_OLTP.dbo.Patient as P on
M.HospitalMasterID = P.HospitalMasterID and
M.PatientID = P.PatientID
Left Outer Join RptSys.dbo.Ref_User as U on
M.EnteredMasterID = U.UserMastID
Where
Cast(M._CreateDateTime as Date) = #StartDate and
M.TxnCode = 'RemCall' and
U.UserName is not null
Does anyone have any suggestions on how to speed this up? I know it is the cast part that is killing it.
Thanks,
Using function for a column makes SQL Server both cast every single row in the table it's comparing and preventing index usage, you should do it like this:
Declare #StartDate Date, #EndDate Date
set #StartDate = GetDate()
set #EndDate = dateadd(day, 1, #StartDate)
select
...
where
M._CreateDateTime >= #StartDate and
M._CreateDateTime < #endDate
ALTER PROCEDURE [dbo].[spInsert]
(#PlanName Varchar(50)=null
,#StartDate Datetime
,#EndDate Datetime
,#ModifiedBy Varchar(100)=null
,#ReturnValue Int Out)
As
BEGIN
IF NOT EXISTS(SELECT PlanName FROM dbo.tblPlan WHERE PlanName=#PlanName)
BEGIN
IF((SELECT COUNT(*) FROM tblPlan WHERE StartDate <= #StartDate AND EndDate <=
#EndDate)<0)
BEGIN
INSERT INTO dbo.tblPlan VALUES(3,#PlanName,#StartDate,#EndDate,#ModifiedBy,GETDATE(),
(SELECT DATEDIFF(DD,#StartDate,#EndDate)))
SET #ReturnValue=1;
END
ELSE
SET #ReturnValue=-2;
END
ELSE
SET #ReturnValue=-1;
END
I am trying to achieve the below thing.I want to check user supplied startDate and Enddate is in between the existing table startdate and enddate. if any of the date of user supplied date range is in between the tables start date and end date,it should return -2,if the record does not exists it should insert the details..
I Could not achieve this logic.where i went wrong ..please suggest me any solution to this.
EDIT:First Consditon check whether planName is exists or not,If not exists then want to check Start and End Date already existed or Not(Including start and End)
I tried two ways as suggested mentioned in the replies.
eg:If existing start and end range is Start-2013-10-09,End-2013-10-15,If am going to insert another plan then the start and end date of this plan should not fall between 9th-15th october and start and End date should not be 9th or 15 th both.
ONE:IF((SELECT COUNT(*) FROM tblPlan WHERE StartDate <= #StartDate AND EndDate <=
#EndDate)=0)
Result: It does not insert any data, even it is out of previous date. or with in the
range
SECOND:IF((SELECT COUNT(*) FROM tblPlan WHERE StartDate>=#StartDate AND
EndDate<=#EndDate)=0)
RESULT: It insert the date with out Considering the above condition.
I think you need to change your if from
IF((SELECT COUNT(*) FROM tblPlan WHERE StartDate <= #StartDate AND EndDate <= #EndDate)<0)
to
IF((SELECT COUNT(*) FROM tblPlan WHERE StartDate <= #StartDate AND EndDate >= #EndDate)=0)
Which should ensure that #StartDate and #EndDate is between StartDate and EndDate and test for =0
COUNT(*) can never be smaller than zero like your code suggests.
It's either a positive integer (which is greater than zero), or null, which will also return false on any arithmetic condition.
try the below :
ALTER PROCEDURE [dbo].[spInsert]
(#PlanName Varchar(50)=null
,#StartDate Datetime
,#EndDate Datetime
,#ModifiedBy Varchar(100)=null
,#ReturnValue Int Out)
As
BEGIN
IF NOT EXISTS(SELECT PlanName FROM dbo.tblPlan WHERE PlanName=#PlanName)
BEGIN
IF((SELECT COUNT(*) FROM tblPlan WHERE StartDate >= #StartDate AND EndDate <=
#EndDate)=0)
BEGIN INSERT INTO dbo.tblPlan
VALUES(3,#PlanName,#StartDate,#EndDate,#ModifiedBy,GETDATE(),
(SELECT DATEDIFF(DD,#StartDate,#EndDate)))
SET #ReturnValue=1;
END
ELSE
SET #ReturnValue=-2;
END
ELSE
SET #ReturnValue=-1;
END
As count always return positive value or zero. so your first condition always being false.
*UPDATE:*
you want to say if Sdate is '12-12-2013' and edate is '15-12-2013' then you don't want to considers these dates in check if so then try replace the query with below:
IF((SELECT COUNT(*) FROM tblPlan WHERE StartDate > #StartDate AND EndDate <
#EndDate)=0)
If you're wanting to check whether the period defined by #StartDate,#EndDate overlaps with any period defined by the values in the StartDate,EndDate columns for a particular row, then the actual comparison that you want to perform is:
StartDate < #EndDate AND EndDate < #StartDate
(With appropriate adjustments of < to <= depending on whether you want to consider two periods such that one starts at the exact time that the other finishes as overlapping or not)
The logic is - Two periods overlap if both of the following conditions are true:
period 1 starts before period 2 ends
period 2 starts before period 1 ends
Other notes -
A COUNT will never be <0 so that part of the logic is incorrect. If you merely want to determine whether any rows exists, use EXISTS (as you already have once) - don't force a COUNT if you don't actually need to know how many rows match your criteria.
I also find it slightly suspect that your first query considers PlanName but your second doesn't. Are you sure that this is correct?
I need to find the last occurence of a date (in my case a static date 1st of may)
I made this which works but i know this can be done in a much smarter way
declare #lastmay date
set #lastmay = DATEADD(YY,YEAR(GETDATE())-2000,'20000501')
IF #lastmay <= GETDATE()
BEGIN
SET #lastmay = DATEADD(YY,-1,#lastmay)
END
When you are working with dates in SQL it can be a real help to have a Dates utility table on your database that you can then compare against.
This article discusses it well: http://www.techrepublic.com/blog/datacenter/simplify-sql-server-2005-queries-with-a-dates-table/326
If you implemented that your queries could become quite simple such as (using columns from article)
Declare #lastmay date
Select #lastmay = DateFull
from DateLookup
where MonthNumber = 5
and MonthDay = 1
and Datefull < getdate()