I have a DateTime column row and I declare a date string:
Row:
2010-08-27 13:45:55
My string:
'2010-08-27'
How can I check if that string is in that row ?
I tried the following query:
declare #year as nvarchar(4)
declare #month as nvarchar(2)
declare #day as nvarchar(2)
set #year = '2010'
set #month = '08'
set #day = '23'
select * FROM [dbo].[customer_import] CsrImport
where
(YEAR(CsrImport.import_date) = #year
AND MONTH(CsrImport.import_date) = #month
AND DAY(CsrImport.import_date) = #day)
but I see that it returns all rows (even that are not contains that date)
Sql server : ISDATE (Transact-SQL)
----Invalid date
SELECT ISDATE('30/2/2007')
RETURNS : 0 (Zero)
----Valid date
SELECT ISDATE('12/12/20007)'
RETURNS : 1 (ONE)
----Invalid DataType
SELECT ISDATE('SQL')
RETURNS : 0 (Zero)
Like this, this will also be able to use the index, do not use function on the column itself..it is not SARGable!!
where import_date >= convert(datetime,#year + #month + #day)
and import_date < convert(datetime,#year + #month + #day) + 1
The best way for you would be to use dates and not 3 different parameters, what if someone passes in 13 for month?
Here is an example which checks that the values that are passed in can be converted to a date, if not it will show an error message
DECLARE #year AS NVARCHAR(4)
DECLARE #month AS NVARCHAR(2)
DECLARE #day AS NVARCHAR(2)
SET #year = '2010'
SET #month = '08'
SET #day = '23'
DECLARE #date DATETIME
IF ISDATE(#year + #month + #day) = 0
BEGIN
RAISERROR('values passed in are not a valid date',16,1)
RETURN
END
ELSE
BEGIN
SET #date = #year + #month + #day
END
SELECT * FROM [dbo].[customer_import] CsrImport
WHERE import_date >=#date
AND import_date < #date + 1
That should work, howabout if you make the values INTS
declare #year as INT
declare #month as INT
declare #day as INT
set #year = 2010
set #month = 08
set #day = 23
select * FROM [dbo].[customer_import] CsrImport
where
(YEAR(CsrImport.import_date) = #year
AND MONTH(CsrImport.import_date) = #month
AND DAY(CsrImport.import_date) = #day)
EDIT: Make sure all the statement is highlighted when you run it too. As simple as it seems, is it possible you mised the where clause if you highlighted the statement.
Just turn the datestring into a date (or datetime) variable and use a where clause:
Since your table has times in it, you have to strip them out or compare them to the midnioght before and after
Declare #myDate DateTime
Set #myDate = 'August 23 2010'
Select * FROM [dbo].[customer_import] CsrImport
Where DateDiff(day, myDate,import_date) = 0 -- Not Sargable
or
Declare #myDate DateTime
Set #myDate = 'August 23 2010'
Select * FROM [dbo].[customer_import] CsrImport
Where import_date) Between #mydate And #Mydate + 1 -- Sargable
Related
I am trying to mimic this calculation from Excel into T-SQL.
The first value is "7/25/2021 6:44:00 AM"
The second value is "7/25/2021 1:10:00 PM"
I am trying to come up with the value of 0.35138..
In SQL table, both values are currently in nvarchar(max) data type.
I am trying to write SQL Function, and I am stuck with process of Convert or Cast and do the calculation of two values.
So far, this is what I have:
CREATE FUNCTION [dbo].[fn_break_cal] (
#Punch_Start nvarchar(max),
#Punch_End nvarchar(max)
)
RETURNS nvarchar(max) AS
BEGIN
DECLARE #return_value nvarchar(max);
SET #return_value =
CONVERT(varchar, #Punch_Start, 103)
RETURN #return_value
First, I am not sure how to do subtraction after I convert into date or datetime.
Whenver I use Datediff, output is Integer, and I am not sure how to make it to numeric like (0.35133..).
What is best approach of dealing with data from nvarchar(max) --> calculation of date/datetime?
Thanks in advance.
Please refer to the below added function and the function call. I am not sure why you return nvarchar(max) value in the function. I changed that to Decimal. I used CAST to cast the nvarchar to datetime. you can use TRY_CAST as well.
ALTER FUNCTION [dbo].[fn_break_cal] (
#Punch_Start nvarchar(max),
#Punch_End nvarchar(max)
)
RETURNS decimal(36, 8) AS
BEGIN
DECLARE #return_value nvarchar(max);
SET #return_value = DATEDIFF(MINUTE, CAST(#Punch_Start AS datetime2) , CAST(#Punch_End AS datetime2) ) / (24* 60.0)
RETURN #return_value
END
Function call with params and return value:
Select [dbo].[fn_break_cal] ('7/25/2021 6:44:00 AM','7/25/2021 15:10:00 PM') return_value
DECLARE #ps nvarchar(30) = '7/25/2021 6:44:00 AM'
DECLARE #pe nvarchar(30) = '7/25/2021 15:10:00 PM'
SELECT
DATEDIFF(MINUTE, TRY_CONVERT(datetime, #ps), TRY_CONVERT(datetime, #pe)) / (24 * 60.0) AS fraction
SELECT
LEFT(CONVERT(time, TRY_CONVERT(datetime, #pe) - TRY_CONVERT(datetime, #ps)), 5) AS ' hr : mm '
-- more than 24 hrs
DECLARE #ps nvarchar(30) = '7/25/2021 6:44:00 AM'
DECLARE #pe nvarchar(30) = '7/27/2021 15:10:00 PM'
SELECT
CONCAT((DATEDIFF(MINUTE, TRY_CONVERT(datetime, #ps), TRY_CONVERT(datetime, #pe)) / 60),
':',
(DATEDIFF(MINUTE, TRY_CONVERT(datetime, #ps), TRY_CONVERT(datetime, #pe)) % 60)) ' hr : mm '
I need to create a function in DB2 which will retrieve year from the current date, based on a certain logic
If the number of the month of the current date is smaller and equal than 6 (=any month prior to June) then the previous year is the ‘reference year’
Else if the number of the month of the current date is larger than 6 (=any month after June!) then the current year is the ‘reference year’.
Examples:
The reference year for date ‘4/9/2019’ is 2018 , since 4 <= 6
The reference year for date ‘9/3/2019’ is 2019, since 9 > 6
Below is an example for the implementation for SQL Server:
CREATE FUNCTION dbo.getReferenceYear()
RETURNS int
AS
BEGIN
DECLARE #ret int;
SELECT #ret = MONTH(GETDATE())
IF (#ret <= 6)
SET #ret = (YEAR(GETDATE()) -1);
Else
SET #ret = (YEAR(GETDATE()) );
RETURN #ret;
END;
I need the same in db2.
Below is what I have tried
CREATE FUNCTION dbo.getReferenceYear()
RETURNS INT
BEGIN ATOMIC
DECLARE _month INT;
DECLARE _year INT;
SET _month = SELECT MONTH (current timestamp) FROM sysibm.sysdummy1
if(_month<=6)
SET _year = (SELECT YEAR (current timestamp) FROM sysibm.sysdummy1) -1
ELSE
SET _year = (SELECT YEAR (current timestamp) FROM sysibm.sysdummy1)
RETURN _year
END
Here is one way to do in in Db2-LUW:
CREATE or replace FUNCTION dbo.getReferenceYear()
RETURNS INT
BEGIN ATOMIC
declare v_nowts timestamp default current timestamp;
declare v_year int;
set v_year= year(v_nowts);
if ( month(v_nowts) <= 6 ) THEN
SET v_year = v_year -1;
END IF;
RETURN v_year ;
END
CREATE FUNCTION dbo.getReferenceYear()
RETURNS INT
as
BEGIN
DECLARE #month INT,#year INT;
SET #month = SELECT MONTH (ColumnName) FROM TableName
if(_month<=6)
SET #year = (SELECT YEAR (ColumnName) FROM TableName -1)
ELSE
SET #year = (SELECT YEAR (ColumnName) FROM TableName)
RETURN #year
END
Or if you don't have any column for the date and if you want to apply the same logic for the current date, then-
CREATE FUNCTION dbo.getReferenceYear()
RETURNS INT
as
BEGIN
DECLARE #month INT,#year INT;
SET #month =( SELECT MONTH (GETDATE()) )
if(#month<=6)
SET #year = (SELECT YEAR (GETDATE())-1)
ELSE
SET #year = (SELECT YEAR (GETDATE()) )
RETURN #year
END
I would do it like this
CREATE FUNCTION getReferenceYear()
RETURNS SMALLINT
RETURN YEAR(CURRENT DATE) - CASE WHEN MONTH(CURRENT DATE) <= 6 then 1 ELSE 0 END
I have an table include 1 column ID and 12 columns month (Month01 to Month12). If i have an parameter #month=9, how can i compare to get column Month01 to Month09 without Month10, Month11, Month12. Please help me!
Simo's answer is more elegant, but below is an alternative "basic" way to do this:
DECLARE #month INT
SET #month = 9
IF #Month = 1
BEGIN
SELECT Id, Month01
FROM MonthlyData
END
IF #Month = 2
BEGIN
SELECT Id, Month01, Month02
FROM MonthlyData
END
-- Repeat for months 3-9
IF #Month = 9
BEGIN
SELECT Id, Month01, Month02, Month03, Month04,
Month05, Month06, Month07, Month08, Month09
FROM MonthlyData
END
-- Repeat for months 10-12
See my SQL Fiddle.
declare #str varchar(1000)
SELECT #str= coalesce(#str + ', ', '') + a.name
FROM (
Select name from sys.columns
where object_id = OBJECT_ID('table_months')
and isnumeric(right(name,2))= 1 and name like 'month%'
and cast(right(name,2) as int) < '03') a
-- Instead of '03' you use a variable and assign required moths number
declare #sql nvarchar(100)
set #sql = 'select ID, '+ #str+' from table_months'
exec sp_executesql #sql
you may try this out also :)
DECLARE #month int = 9
DECLARE #Sql nvarchar(100) =''
DECLARE #pos int = 1
WHILE(#pos <= #month)
BEGIN
SET #Sql = #Sql + (',month' + right('00'+ rtrim(#pos), 2))
SET #pos = #pos + 1
END
SET #Sql= 'SELECT ID ' +#Sql + ' FROM table'
EXEC sp_executesql #Sql
DECLARE #month int
DECLARE #tableName nvarchar(128)
SET #month = 9;
SET #tableName = 'months' -- YOUR TABLE's NAME
DECLARE #query nvarchar(2048)
SET #query =
'SELECT id, ' + STUFF((SELECT DISTINCT ', ' + name
FROM sys.columns WHERE name LIKE'Month%'
AND object_id = OBJECT_ID(#tableName)
AND CONVERT(INT, RIGHT(name, 2)) <= #month
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
+ ' FROM ' + #tableName;
EXEC(#query)
There is following statements in my query:
declare #d int = day(getdate())
declare #m int = month(getdate())
declare #y int = year(getdate())
select #d,#m,#y
So I want to convert #d,#m,#y to date type(format) and use it as date parameter!
Thanks
Try this:
declare #d int = day(getdate())
declare #m int = month(getdate())
declare #y int = year(getdate())
DECLARE #myDate DATETIME
SET #myDate = CAST (#y AS NVARCHAR(4))+'-'+CAST (#m AS NVARCHAR(2))+'-'+CAST (#d AS NVARCHAR(2));
select #myDate
If u dont cast the values you will get some other date.
This will do it in a portable fashion:
select DATEADD(year,#y - 2000,DATEADD(month,#m - 1, DATEADD(day,#d - 1,
'20000101')))
However, if your motivation was just to get the current date without any time portion, I'd just do:
select DATEADD(day,DATEDIFF(day,0,GETDATE()),0)
Or even
select CONVERT(date,GETDATE())
select *
from WeatherForecast
where Cast( cast(year as nchar(4)) + '-' + cast(month as nchar(2)) + '-' + cast(day as nchar(2)) as date) between getdate() - 7 and getdate()
I writing code to determine how many days in a year. I am trying to keep it really simple.
I found code that I think is very clean to determine a leap year. I am passing the inputted date using DATEPART(Y,#Year) to the leap year program and some how am not getting the correct results so I has to be in my SQL code to process the input date as the correct bit is returned.
Here is the code for the Leap Year:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[FN_Is_Leap_Year]
(
-- the parameters for the function here
#year int
)
RETURNS BIT
AS
BEGIN
RETURN (select case datepart(mm, dateadd(dd, 1, cast((cast(#year as varchar(4)) + '0228') as datetime)))
WHEN 2 THEN 1
ELSE 0 END)
END
Here is the code I wrote to process the input date & get the # days in a year:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[FN_Get_Days_In_Year]
(
#InputDT varchar(10)
)
RETURNS int
AS
BEGIN
DECLARE #Result int,
#Year int
Set #Result =
CASE
WHEN dbo.FN_Is_Leap_Year(Datepart(yyyy,#Year)) = 0 Then 365
WHEN dbo.FN_Is_Leap_Year(Datepart(yyyy,#Year)) = 1 Then 366
END
RETURN #Result
END
Got it working!!
GO
ALTER FUNCTION [dbo].[FN_Get_Days_In_Year]
(
#InputDT int
)
RETURNS varchar(3)
AS
BEGIN
Declare #Year int,
#RetVal bit,
#Result varchar(3)
Set #Year = datepart(yy, #InputDT)
Set #RetVal = dbo.FN_Is_Leap_Year(Datepart(yy,'2012'))
Set #Result = CASE #RetVal
WHEN 1 THEN 366
ELSE 365
End
Return #Result
END
Modified version of the above answer :
DECLARE #year INT,
#DaysInYear INT
SET #year = 2011
SELECT #DaysInYear = CASE DATEPART(mm, DATEADD(dd, 1, CAST((CAST(#year AS VARCHAR(4)) + '0228') AS DATETIME)))
WHEN 2 THEN 366 ELSE 365 END
SELECT #DaysInYear 'DaysInYear'