Concatenate two date parts - sql

I'm trying to build a report based on a ticketing system we use. I'm quite new to SQL and just getting my head around it but the issue I am facing at the moment is trying to join two fields into a date. The data in the table is in displayed as Month_Number and Year_Number
I need to do a comparison with a datetime field to see if it is between the date range. I've searched a fair bit about concatenating the two fields I have into a date but unfortunately have come up short.

You can simply do this to concatination for youe Month & Date Part.
declare #month varchar(10);
declare #year varchar(10)
set #month = 5
set #year = 2014
You can choose whatever you feel for you is the best
select #month+'-1-' +#year as Your_Date
select '1-'+#month+'-' +#year as Your_Date
select #year+'-'+#month+'-1' as Your_Date
Output
5-1-2014
1-5-2014
2014-5-1
To Retrieve the date from your Table in SQL you can do like this
select month_number+'-1-' +year_number as Your_Date
from table_name
If you want to change the style of the displaying output then you can use Convert Function

Related

SQL Server end of month

Suppose there is one date in int format 20191229, I want to find end of month and check if it's end of month is of 31 days or 30 days in SQL Server
You can try this from the reference. The given answer will not work for the integer data type but it will work in the varchar datatype date value. Storing Date values in integer is not a good idea, so as suggested by Larnu change the data type in either date or varchar.
SELECT
Day(EOMONTH(Cast('20191229' as Date))) end_of_month;
If you want the amount of days within a month, as you need the days as an integer, you should go for this. This is the most robust built, but also the more complex one, as to make sure the Integer value is processed correctly:
SELECT DATEPART(DAY,EOMONTH(CAST(CAST('20191229' AS NCHAR(8)) AS DATE))) AS Days
Result:
Days
31
If you want to add an IF evaluation to your selected date(s), you can do this by add an IIF-clause where it evaluates whether or not the end of month is 31 or not. If you want to use a columnname instead of the date, just substitute #Date with the columnname. I've just added the variable #Date instead of '20191229' to make it more illustrative/understandable. You can change the True/false descriptions to whatever you like in the query.
DECLARE #Date AS int
SET #Date = '20191229'
SELECT
IIF (
DATEPART(DAY,EOMONTH(CAST(CAST(#Date AS NCHAR(8)) AS DATE))) = '31'
,'True'
,'False'
) AS Days
Output:
Days
True

Query Datetime Declaration

I'm having trouble with a Datetime column in a table while adding declaration on a stored procedure.
I want to set #EventTime as a day of the week without modifying the column..
More like a catch.
For example:
declare #EventTime datetime
set #EventTime = (select EventTime
from _LogClients
where ClientID = #ClientID)
if (#EventTime like '%2-2%) -- As a day of a week not as a numerical date.
- - Datetime preview:2019-01-22 17:47:00
Any help regarding that matter?
Note:
The EventTime is used on a Stored Procedure which runs on a certain event that occur.. However, the database is a Game one, so the logger is based on the server files, I need to know if I'm able to make the EventTime declaration able to read the datetime from the column as weekday in order to execute a certain query for that day (Not SQL Agent based though.. that's a different story).
I'm not sure from your question if you are trying to get the numerical representation of the actual day of the week (like Sunday would be "1", Monday as "2", etc.. ) or if you just need the day of the week as a word from a date.
Here is your code modified to use the word for the day of the week (please note you could have used the DateName within the select statement but then you'd need to change the type of #EventTime to a nVarchar() or nchar) :
declare #EventTime datetime
set #EventTime = (select EventTime
from _LogClients
where ClientID = #ClientID)
if (DATENAME(dw,#EventTime) like '%Tuesday%)
If you wanted the numerical equivalent use:
if (DATEPART(dw,#EventTime) = '1' -- Testing for Sunday day name

Can't convert Datetime to Int

I am trying to SELECT rows based on two values with this stored procedure:
ALTER PROCEDURE [dbo].[MYSelect]
-- Parameters with default values
#MitarbeiterId AS int,
#Wann AS datetime2(7)
AS
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT *
FROM [Plan]
WHERE RefMitarbeiterId = #MitarbeiterId
AND Jahr <= YEAR(#Wann)
AND Monat <= MONTH(#Wann)
AND Abgeschlossen = 0
The problem is the following part:
AND Jahr <= YEAR(#Wann)
AND Monat <= MONTH(#Wann)
I don't know why this part is causing a (syntax) problem. With this lines included, using MSSQL Studio, I receive an error unable to convert DateTime to Integer. Removing these returns results and has no syntax error. I use YEAR() and MONTH() elsewhere, so I'm confused why there is a problem here.
This is the Plan table:
The conditions
AND Jahr <= YEAR(#Wann)
AND Monat <= MONTH(#Wann)
separate the condition to year and month.
It doesn't mean where the years and month are less then the parameter but where year is less or equal than the year of the parameter and the month is less or equal than the month of the parameter.
Using today (2014-06-30) as parameter your query will return every row where with Monat between 1 and 6 for the past and current year: the rows from December 2013, for example, will not be returned.
To get all the rows before the date of the parameter you'll need to change the conditions to
AND ((Jahr = YEAR(#Wann) AND Monat <= MONTH(#Wann))
OR Jahr < YEAR(#Wann))
After testing different ways of running this Procedure,
i now think its a bug if you use the View with a Datetime Parameter in SQL Server Manangement Studio
because i tested
EXEC
which works well
then removed my parameters
this returns an error which tells me that it was unable to convert '01.07.2014 00:00:00' to a datetime but it returns the right Rows
if i now do it again with my parameters and add my values
i get an exception which tells me the same think like the error above so i have to remove the ' and then i get the unable to convert DateTime to Integer which it's a bug in my opinion

T-SQL 2008 Convert Date and time string to datetime

I have two columns in my table, one to capture time and one to capture date. Unfortunately, both are varchar(). I need to take the two fields, concatenate them together, and then convert them to datetime.
I am trying to accomplish that with this:
select CONVERT(datetime,(select txt_returned_date+' '+CONVERT(varchar(20),CONVERT(TIME,txt_time_returned))),126)
from table_name
I am getting this error message:
Conversion failed when converting date and/or time from character string.
The date is being captured as "20130308" as a string. Time is being captures as "4:27 PM" as a string
What I am doing here is converting the string of the time to TIME, then back to varchar. Then I am concatenating them together. This works by itself, but once I introduce the CONVERT(datetime) to the whole query, it is giving me the error.
Any help to try to accomplish this is helpful. Thanks!
You can concatenate the DATE and TIME values together once they have been converted to a DATETIME. Here's a sample to play with that shows concatenating a DATE column and a TIME column that have been stored as VARCHAR:
-- Set up some variables to test with
DECLARE #myTime TIME = GETDATE()
, #myDate DATE = GETDATE()
, #myTimeTxt VARCHAR(16)
, #myDateTxt VARCHAR(10);
-- Initialize your variables
SELECT #myTimeTxt = #myTime
, #myDateTxt = #myDate;
-- Display your separated values
SELECT #myDateTxt, #myTimeTxt;
-- Display your concatenated value
SELECT CAST(#myDateTxt AS DATETIME) + CAST(CAST(#myTimeTxt AS TIME) AS DATETIME);
You can use this option
DECLARE #date date = '20010101',
#time time = '01:01:01'
SELECT CAST(#date AS datetime) + #time
Result:2001-01-01 01:01:01.000
Demo on SQLFiddle
Are you using SQL 2012? If so you may be able to use the datetimedromparts function to achieve this. If not for this specific example, it's always good to know for the future :)
http://technet.microsoft.com/en-gb/library/hh213233.aspx

A better way? Have date in query always use a date in the current year without maintenance

SELECT Date_Received, DateAdd(Year, DateDiff(year, Cast('3/01/2010 12:00:00AM' as DateTime) ,
GetDate())-1, Cast('3/01/2010 12:00:00AM' as DateTime)) as minimum_date
FROM [Volunteers].[dbo].[Applications]
WHERE Date_received >= DateAdd(Year, DateDiff(year, Cast('3/01/2010 12:00:00AM' as DateTime),
GetDate())-1, Cast('3/01/2010 12:00:00AM' as DateTime))
In several subqueries where I need to check that a date is within an acceptable range. I need to avoid using a simple constant as I really don't want to update it or a config file each new school year.
My current solution is to enter the date into the query and use some complicated DATEADD tricks to get the current year(or previous year) into the date I am using in the comparison. The exact code is above. Is there a cleaner way for me to do this?
Thanks
Edit
The business requirement is to find applications submitted between 3/01 and 7/31.
We are running background checks and it costs us money for each check we do. Identifying applications submitted during this time period helps us determine if we should do a full, partial or no background check. I will also need to check if dates concerning the previous year.
We will be doing this every year and we need to know if they were in the current year. Maintaining the queries each year to update the dates is not something I want to do.
So I am looking for a good technique to keep the year parts of the dates relevant without having to update the query or a config file.
Old TSQL trick: cast the date to a string in a format that starts with the four-digit year, using substring to take the first four characters of that, cast it back to a date.
Actually, the reason that it's an old TSQL trick is that, if I recall correctly, there wasn't a year() function back then. Given that there's one now, using year( getdate() ) , as others' have answered, is probably the better answer.
SELECT YEAR(GETDATE())
will give you the current year.
If you need to query by month and year a lot, you should also consider making those properties into persisted, computed fields:
ALTER TABLE dbo.Applications
ADD DateReceivedMonth AS MONTH(Date_Received) PERSISTED
ALTER TABLE dbo.Applications
ADD DateReceivedYear AS YEAR(Date_Received) PERSISTED
SQL Server will now extract the MONTH and YEAR part of your Date_Received and place them into two new columns. Those are persisted, e.g. stored along side with your table data. SQL Server will make sure to keep them up to date automatically, e.g. if you change Date_Received, those two new columns will be recomputed (but not on every SELECT).
Now, your queries might be a lot easier:
SELECT (list of fields)
FROM dbo.Applications
WHERE DateReceivedYear = 2010 AND DateReceivedMonth BETWEEN 3 AND 7
Since these are persisted fields, you can even put an index on them to speed up queries against them!
Is there any reason you cannot simply use the Year function?
Select Date_Received
, Year(GetDate())
- Year('3/01/2010 12:00:00AM') - 1
+ Year('3/01/2010 12:00:00AM')
From [Volunteers].[dbo].[Applications]
Where Date_received >= ( Year(GetDate())
- Year('3/01/2010 12:00:00AM') - 1
+ Year('3/01/2080 12:00:00AM') )
Another way would be to use a common-table expression
With Years As
(
Select Year(GetDate()) As CurrentYear
, Year('3/01/2010 12:00:00AM') As ParamYear
, Year('3/01/2080 12:00:00AM') As BoundaryYear
)
Select Date_Received
, CurrentYear - Years.ParamYear - 1 + Years.ParamYear
From [Volunteers].[dbo].[Applications]
Cross Join Years
Where Date_received >= ( Years.CurrentYear
- Years.ParamYear - 1 + Years.BoundaryYear )
TSQL Function returns four digit year dependent on year. This behaves much like the standard SQL YEAR functions [Thomas - nod] which 'CAN' be tweaked using sp_configure on the advanced options, however, the code below is provided as a framework for CUSTOM requirements and can be modified as required. e.g. return as int, use with standard DATETIME functions in SQL to achieve what is needed. e.g. When working with "dirty" data I had to migrate, I used it with the PATINDEX() function to strip non-numeric values etc.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Andrew McLintock
-- Create date: 13 July 2016
-- Description: Return 4-digit YEAR
-- =============================================
/*
SELECT Staging.fn_4year('06')
SELECT Staging.fn_4year('56')
SELECT Staging.fn_4year('99')
SELECT Staging.fn_4year('1906')
SELECT Staging.fn_4year('2025')
*/
CREATE FUNCTION Staging.fn_4year
(
#year_in varchar (4)
)
RETURNS varchar(4)
AS
BEGIN
DECLARE #yeartmp int, #Retval varchar(4)
SET #yeartmp = CAST(REPLACE(#year_in,' ','') AS INT)
IF LEN(CAST(#yeartmp AS Varchar)) = 4
BEGIN
Return cast(#yeartmp as varchar(4))
END
IF LEN(#year_in) = 2
BEGIN
SET #Retval = CAST(iif(#yeartmp > 49, #yeartmp + 1900, #yeartmp + 2000) AS varchar(4))
END
RETURN #Retval
END
GO
Consider keeping a set of datetime variables help readability and maintainability. I'm not sure I've captured all your requirements, especially with reference to 'previous year'. If it's as simple as finding applications submitted between 3/01 and 7/31, then this should work. If you need to determine those that were submitted Aug 1 (last year) through Feb 28 (current year), this solution could be modified to suit.
DECLARE #Start smalldatetime, #End smalldatetime, #CurrYear char(4)
SELECT #CurrYear = YEAR(getdate())
SELECT #Start = CAST( 'mar 1 ' + #CurrYear as smalldatetime),
#End = CAST( 'jul 31 ' + #CurrYear as smalldatetime)
SELECT *
FROM Applications
WHERE Date_Received
BETWEEN #Start AND #End