I have a SQL Server table that stores Time as follows (in a varchar column):
08 SEP 2015 09:15:16
08 SEP 2015 09:15:22
08 SEP 2015 09:15:22
08 SEP 2015 09:15:22
08 SEP 2015 09:15:26
08 SEP 2015 09:15:27
08 SEP 2015 09:15:31
I want to write a query that can give me all entries that are in a particular month and year. Like 'JAN 2016' and so on.
I am using SQL Server.
If, you are not able to change the type of dates that you have then you will need to cast them with format() function to format the date(MMM yyyy) available from 2012+
SELECT
FORMAT(CAST(<column> AS DATE), 'MMM yyyy') as dates
FROM table t
You could also use the datepart() function to filter the dates
WHERE
DATEPART(MONTH, dates) = 1 and DATEPART(year, dates) = 2015
In order to just the want to display the counts use count() function
SELECT COUNT(*)
FROM table
WHERE DATEPART(MONTH, dates) = 1 AND
DATEPART(year, dates) = 2015
As already mentioned in the comments, I would recommend to change this data type to a date/timestamp field in order to avoid risk of data inconsistency and/or having part of your application crashing when trying to convert string (that do not respect the format of a date) to a date object.
Now if and only if it is not feasible in short term, you have two ways to proceed:
1. data conversion:
The first one is to extract all the records from the table and convert them to date type before doing the comparison,
however if there is at least one varchar that is not a well formed date, your query will fail.
2. work with string:
Another way of doing is to query your DB directly using a varchar like described hereunder to avoid those conversion issues:
select * from table_A where date_column like '%JAN 2016%'
However query using like are kind of slow and should only be used as a temporary work-around, in long term adapt your data model to ease
your life and have a more stable/robust application.
Last but not least, try to run some queries to check if there are not already some wrong data (format or strings that are not dates) inserted in your DB. You might face already some data inconsistency issues.
Related
Suppose we have the following column from a table (type: character):
date
Wed May 31 21:00:01 +0000 2017
Wed May 31 20:59:59 +0000 2017
I'm trying to sort this table by ascending order, but it won't work because it does so alphabetically given that the column type is character rather than date. Any ideas how to change the type in SQL to date so that it will sort properly?
Thanks!
Converting answer from comments as poster said that worked
SELECT *
FROM YourTableName
ORDER BY CAST(DateInStringFormatFromTable as DateTime)
This will take a LONG time every time you run the query.
You should change the format in the table to be datetime. Or create 2nd column and update it to be a datetime and format the data into that column, then sort by that.
Updated to give other option based off comments:
You can try convert, instead of cast to see if that works for your decending
SELECT *
FROM YourTableName
ORDER BY CONVERT(DATETIME, DateInStringFormatFromTable, 102) DESC
I am trying to place data corresponding to a certain month into a temp table from an SQL database.
DROP TABLE
#ComPAIR_Alliance_Table
SELECT
IMOno
,period
,[service]
,alliances
INTO
#ComPAIR_Alliance_Table
FROM
com_COMPAIR.dbo.Data_BlueWaterCapacity_US_2
WHERE
LEFT(period, 7) = '2015-03'
SELECT
*
FROM #ComPAIR_Alliance_Table
The period field is in the following format: 2015-03-29 00:00:00.000
However, my code just returns an empty temp table with the right column names but no rows (even though I know for sure rows with that date exist in my table). I have already made sure that the period column is indeed a string by using is.numeric.
Could someone please help me out with what the problem could be?
Thanks!
If it is a date/datetime/datetime2 then you can compare it with 2015-03 like:
WHERE period >= '2015-03-01'
AND preiod < DATEADD(MONTH, 1, '2015-03-01')
In case there is confusion:
The above will match all March 2015 dates such as 2015-03-31, 2015-03-31 23:59:59 and 2015-03-31 23:59:59.9999999
The above is sargable: the DATEADD part does not depend on the table rows
Guessing Period is a date. If it is, stop treating it like a varchar, it isn't one. If you want values from March 2015 then do:
WHERE period >= '20150301'
AND period < '20150401'
LEFT is doing some weird stuff, because LEFT causes an implicit cast to String from Date. You can see this question for more information, but you're getting exactly what you told SQL to get - a join on rows where the left 7 characters of period equal '2015-03' which will not happen, since you're liking comparing against something like 'Jan 01'
The LEFT function needs to implicitly convert your datetime column to a varchar value to do it's work. SQL Server is choosing the varchar format of the date based on it's internationalization settings. On my server, its Mar 29 2015 12:00AM, and LEFT yields Mar 29. That's why it's not equal to 2015-03.
You should treat your column as a datetime and then perform the comparison using a valid datetime comparison, like this :
WHERE period BETWEEN '1/1/2015' AND '1/31/2015'
the date is stored as a date type. You may want to try
where convert(varchar(20), period,121)
which would convert it to string...
How can one convert the string "01 December 2016" to a date type in SQL Server?
CONVERT(date, '01 December 2016', 106)
Expected date outcome "01 Dec 2016"
If 2012+ you can use Format()
Select Format(convert(date,'01 December 2016'),'dd MMM yyyy')
Returns
01 Dec 2016
It is very dangerous to work with culture specific date/time formats and it is even worse to work with language and culture specific formats...
If ever possible store date/time values in appropriate types!
In my (german) system a direct cast or convert would break due to "December", which is "Dezember" in Germany. Have a look at this:
SET LANGUAGE English; --try the same with "German"
DECLARE #d VARCHAR(100)='01 December 2016';
SELECT CONVERT(VARCHAR(11),CONVERT(DATE,#d,106),106);
The result
01 Dec 2016
One should never rely on implicit conversions: Call CONVERT with the third parameter in any case!
The third parameter 106 tells SQL Server the date's format (how to parse it). The first CONVERTSs target type is DATE. This - now properly represented! - date can be converted again to VARCHAR(11) with 106 as third parameter now specifying the output format.
For deeper insight in language specific date parts you can run this query:
SELECT * FROM sys.syslanguages;
btw: If you are using SQL Server 2012+ you should call FORMAT() as pointed out by John Cappelletti
Have researched a lot, both on this site, and others, but still don't have a valid solution. I have a column of varchar datatype, it contains DateTime data. I need to store only the Date portion in a Date type column. Tried different ways of Cast, Convert, and other functions, but still haven't been able to make it work.
Basically I want to convert this
Tue Apr 26 2016 13:54:53 GMT+0200 (CEST)
to
04/26/2016
Assuming your Day and Month part is always 3 characters long this can be done simply as this:
DECLARE #d VARCHAR(100)='Tue Apr 26 2016 13:54:53 GMT+0200 (CEST)';
SELECT CONVERT(DATE,SUBSTRING(#d,4,12),109);
If this was to easy one would have to find the blank(s) with CHARINDEX, but I don't think so...
The format code 109 means mon dd yyyy hh:mi:ss:mmmAM (or PM) Details here.
And be aware that formats containing language depending parts are directly sent by the devil to create never ending pain... This will not work on a server with a different language setting!
Declare #String varchar(max) = 'Tue Apr 26 2016 13:54:53 GMT+0200 (CEST)'
Select cast(Substring(#String,12,4)+Substring(#String,4,7) as date)
Returns
2016-04-26
Okay a few things here you have a field that looks to be psuedo ISO 8601 but is not the standard. The first question will be: "Where does this come from?" Typically you don't have the 'Tue' or 'GMT' or '(CEST)' in a standard and the offset from Greenwich Meantime is in the format (+/-)##:## NOT (+/-)####. SQL and many other formats can easily accept a standardized string in the ISO 8601 format. Good brief here: https://www.w3.org/TR/NOTE-datetime
That being said you can easily get what you want with a little know how:
DECLARE
#S VARCHAR(128) = 'Tue Apr 26 2016 13:54:53 GMT+0200 (CEST)'
, #Valid VARCHAR(128)
--Legitimate ISO 8601 string:
SELECT #Valid = RTRIM(LTRIM(REPLACE(STUFF(STUFF(#S, 1, 4, ''), LEN(#S)-12, 12, ':00'), 'GMT', '')))
SELECT #Valid
--Legitimate DateTimeOffset
SELECT CAST(#Valid AS DATETIMEOFFSET)
--Now that I have a legimiate DateTimeOffset I can downconvert easily
SELECT CAST(CAST(#Valid AS DATETIMEOFFSET) AS DATE)
--AND... Now that I have a legimate Date I can format it many different ways
SELECT CONVERT(VARCHAR, CAST(CAST(#Valid AS DATETIMEOFFSET) AS DATE), 101)
The real thing to realize here is there is magical conversion of DateTime using the convert function. But you may be wondering 'what if I want it to look different?'. Try this page:
http://www.sql-server-helper.com/tips/date-formats.aspx
I would be leery though of just finding the placement of were things appear to be coming from a string even though I can parse your example. If you are getting things not following a standard you should know why. The main reason being you may be able to get this to work for a specific instance but not be able to repeat this pattern over and over.
What I'm trying to achieve is fairly straight forward, to get one date format to another;
From This: Jan 30 2013 12:00:00:000AM
To This: DD/MM/YYYY or in this case 30/01/2013
However, when it's the 1st to the 9th of the month the date format is missing a zero and there is two spaces, as shown;
Jul 3 2014 12:00:00:000AM
I've hunted round for a solution but without success, the format of the date is unusual and varies depending on the day of the month however this format is generated by an internal system and can't be changed. Would I then have to pattern match in order to change the format? How would I go about doing this?
An example of part of the query is this;
SELECT
PREFIX_TableName.ColumnName1 AS Name,
PREFIX_TableName.ColumnName2 AS E-Mail,
PREFIX_TableName.ColumnName3 AS TransactionDate,
PREFIX_TableName.ColumnName4 AS OrderNumber,
...
The line to be edited is this PREFIX_TableName.ColumnName3 AS TransactionDate,
If DB is SQL Server then
select Convert(varchar(10),CONVERT(date,YourDateColumn,106),103)
If I understood your question, try something like this
declare #dd varchar(50)='Jan 30 2013 12:00:00:000AM'
Select convert(varchar,(CONVERT(date,#dd,103)),103)
Update
SELECT
PREFIX_TableName.ColumnName1 AS Name,
PREFIX_TableName.ColumnName2 AS E-Mail,
convert(varchar,(CONVERT(date,PREFIX_TableName.ColumnName3,103)),103) AS TransactionDate,
PREFIX_TableName.ColumnName4 AS OrderNumber
If you have a Date (or Datetime) column, look at http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-format
SELECT DATE_FORMAT(datecolumn,'%d/%m/%Y') FROM ...
Should do the job for MySQL, for SqlServer I'm sure there is an analog function.
If you have a VARCHAR column, you might have at first to convert it to a date, see STR_TO_DATE for MySQL.
SELECT CONVERT(varchar(11),Getdate(),105)
Try http://www.sql-server-helper.com/tips/date-formats.aspx. Lists all formats needed.
In this case select Convert(varchar(10),CONVERT(date,YourDateColumn,106),103)
change 103 to 104 id you need dd.mm.yyyy