SSRS/TSQL date formatting - tsql

Using the following sample query below in SSRS would return month as single number(1-12). What I want to is to display the date as is something like Jan 2000. How would I go about changing my code to be able to format from single number month to a MMM YYYY format? I tried the formatting in visual studio itself but it is currently returning as MMM YYYY.
select distinct count(*) as Count,
con.STATE,
month(con.sub_Date) as Month,
year(con.sub_Date) as Year
from contract con
group by con.STATE,month(con.sub_date),year(con.sub_date)

I strongly recommend that you perform the formatting of the date at the report level.
Return the date from your query as the first date of the desired period, but then set the format string for the placeholder/text box.
The reason to do this is so that sorting and data manipulation works as expected when the report is exported to Excel.
So I would use a query as:
SELECT DISTINCT
COUNT(*) AS Count ,
con.STATE ,
DATEADD(MONTH, DATEDIFF(MONTH, 0, con.sub_Date), 0) AS FirstOfMonth
FROM
contract con
GROUP BY
con.STATE ,
DATEADD(MONTH, DATEDIFF(MONTH, 0, con.sub_Date), 0)
and then use formatting codes in the report such as MMM, YYYY for display and break the date apart with =Month(fields!FirstOfMonth.Value) if you need the components for grouping. This will allow the users to pivot the data appropriately if needed.
Formatting of the dates is presentation logic, and should be kept out of SQL if possible.

You could add the following into the query to return the pre-formatted month/year as part of the report dataset - maybe easier than trying to reconstruct it at the report level:
select distinct count(*) as Count,
con.STATE,
month(con.sub_Date) as Month,
year(con.sub_Date) as Year,
left(datename(mm, sub_Date), 3) + ' ' + cast(year(sub_Date) as char(4)) as MonthYear
from contract con
group by con.STATE,
month(con.sub_date),
year(con.sub_date),
left(datename(mm, sub_Date), 3) + ' ' + cast(year(sub_Date) as char(4))

I usually prefer to use CONVERT to get partial dates, though I don't see any CONVERT date formats that would leave you cleanly with a MON YYYY output. However, format 106 will get you most of the way there. So combining that with RIGHT() will get you the date in the format you're looking for.
SELECT DISTINCT
COUNT(*) AS Count ,
[con].[STATE] ,
MONTH([con].[sub_Date]) AS Month ,
YEAR([con].[sub_Date]) AS Year ,
RIGHT(CONVERT(CHAR(11), [con].[sub_Date], 106), 8) AS MonthYear
FROM [dbo].[contract] AS con
GROUP BY [con].[STATE] ,
MONTH([con].[sub_Date]) ,
YEAR([con].[sub_Date]) ,
RIGHT(CONVERT(CHAR(11), [con].[sub_Date], 106), 8)

Related

Compare YEAR value in WHERE clause

Using SQL Server 2008 R2 I am trying to compare year values in a where clause like so:
AND year(convert(date, (LEFT(formAuditLog, 10)), 104 )) = year(GETDATE())
But I get this error:
Conversion failed when converting date and/or time from character string
I have also tried this but get that same result:
AND cast(year(convert(date, (LEFT(formAuditLog, 10)), 104 )) as int) = cast(year(GETDATE()) AS INT)
Note - formAuditLog is a string. I am getting the first 10 chars which is always mm/dd/yyyy (I have triple checked this) so I convert as a date and then get the year of this. Based on this info, should I not be able to do this comparison?
Thanks in advance
Added :
Note - When I put this in a select it works. I get the year part of the date I am expecting:
select top 10 year(convert(date, (LEFT(formAuditLog, 10)), 104 )) , * from myTableName
So why would this be allowed in a select but fail in a where clause?
Added : For completeness, there is actually nothing wrong with either of the two SQL bits at the top of this post. As mentioned in the accepted post comment below, it was a leading quote in one formAuditLog records that cause it to fall over
If your formAuditLog column is a string like you suggest and the left 10 characters is equivalent to a date format MM/DD/YYYY. This should have worked for you:
create table mytableName (id int, formAuditLog varchar(50));
insert into mytableName values
(1,'01/02/20141203'),
(2,'01/03/20151203'),
(3,'05/01/20151203');
select
id,
formAuditLog,
cast(left(formAuditLog,10) as date) as DateField,
year(cast(left(formAuditLog,10) as date)) as yearfield
from mytableName
where year(cast(left(formAuditLog,10) as date)) = year(cast(getdate() as date));
Code Demo
for sql server 2008, this should be your where condition
and year(GETDATE()) = case when isdate(LEFT(formAuditLog, 10))=1 then year(convert(date, (LEFT(formAuditLog, 10)))) else 99999 end
For sql server 2012..
AND year( try_parse(LEFT(formAuditLog, 10) as date) ) = year(GETDATE())

Crystal Report-Convert date string (with day of week) to date format

I'm new to crystal report. I have a date in string format like 2015-03-25 (Wed) and I want to convert it to date format like 03/25/2015. I tried with CDate and DateValue but it returned bad date string format. Any suggestions to convert such date string to proper date format?
If you have a DateTime field in Crystal Reports, you will see Date and Time tab option on the Format Editor when you right click on the field and select Format Field menu item. From the Date and Time tab, you may select the desired format and select OK.
It would be recommended to use the formats you want to use.
For eg : if you are giving string format for money or decimal you may not be able to use it at its full,like you may not be able to auto sum and other properties related to the datatype you intend to use
Not to do any thing in the code, Crystal Report have facility to this type of simple format.
#utility, you are near to answer.
As above image, in last Custom Format option, where you just go in Date tab and give format as
http://www.c-sharpcorner.com/UploadFile/mahesh/DateFormatInCR06132007092248AM/DateFormatInCR.aspx
Updated : sorry for above answer, that will work if you have valid date string.
In your case, where any arbitrary string need to convert into other date format. There is 2 option. In both case you have to extract the date and then format as you need and again combined with other sub-string.
Second you already done ie. crsytal report side, grab the date , format it and concatenate. this will slow down as need to process for each row.
SqlServer side - This option is faster from first option.
declare #t nvarchar(16) = '2015-03-25 (Wed)'
--get the acual date select SUBSTRING ( #t, 1, charindex('(' , #t ) -1 )
--above result give the charter datatype, so you first convert into date and then convert into other format select cast( SUBSTRING ( #t,
1, charindex('(' , #t ) -1 ) as date) --convert into date select
convert (varchar(15) , cast( SUBSTRING ( #t, 1, charindex('(' , #t )
-1 ) as date) , 103) --convert into dd/mm/yyyy format
--Above is for your understand, this is the actual execution of your code (Only write the below line) select convert (varchar(15) , cast(
SUBSTRING ( #t, 1, charindex('(' , #t ) -1 ) as date) , 103) + ' ' +
datename(dw, getdate() )
I suggest, go with Sqlserver side.

Problem when extracting year and week number from string in PSQL

Let's say that I have a range of SQL tables that are named name_YYYY_WW where YYYY = year and WW = week number. If I call upon a function that guides a user defined date to the right table.
If the date entered is "20110101":
SELECT EXTRACT (WEEK FROM DATE '20110101') returns 52 and
SELECT EXTRACT (YEAR FROM DATE '20110101') returns 2011.
While is nothing wrong with these results I want "20110101" to either point to table name_2010_52 or name_2011_01, not name_2011_52 as it does now when I concanate the results to form the query for the table.
Any elegant solutions to this problem?
The function to_char() will allow you to format a date or timestamp to output correct the iso week and iso year.
SELECT to_char('2011-01-01'::date, 'IYYY_IW') as iso_year_week;
will produce:
iso_year_week
---------------
2010_52
(1 row)
You could use a CASE:
WITH sub(field) AS (
SELECT CAST('20110101' AS date) -- just to test
)
SELECT
CASE
WHEN EXTRACT (WEEK FROM field ) > 1 AND EXTRACT (MONTH FROM field) = 1 AND EXTRACT (DAY FROM field) < 3 THEN 1
ELSE
EXTRACT (WEEK FROM field)
END
FROM
sub;

How do I format a date in a SQL Where clause?

I have a .NET 2010 app that bangs against a SQL db. On the app side, a user can search on Begin date and End Date. Bot of these are just Month + Year. I then format them so they are complete dates. So when they go to the stored proc they'll look like this...
Begin Date: 1/1/2011
End Date: 5/31/2011
But the date in the db is broken up into 3 int fields, Month,Day & Year, ...of which Day may or may not be filled in (0 if not). It would be ok for this to always default to one when running this query. So if the values in the db were Month=3, Day=0 Year=2011 I would like the sql statement to render as
Where FORMATTEDDATEHERE between '1/1/2011' and '5/31/2011'
I just can't figure out how to format sql fields in a where clause.
Did you try something like
WHERE CONVERT(DATETIME,
CONVERT(VARCHAR(4), [c_year]) + '/'
+ CONVERT(VARCHAR(2), [c_month]) + '/'
+ CONVERT(VARCHAR(2), [c_day]))
BETWEEN '2011/1/1' AND '2011/5/31'
Hope it helps
you could build the date using datadd functions within the WHERE clause EG.
SELECT ...
WHERE DATEADD(Day, field_days-1, DATEADD(Month, field_months-1, DATEADD(Year, field_years-1900, 0))) BETWEEN '1/1/2011' AND '5/31/2011'
Just replace field_days, field_months, field_years with the int fields on the table for days, months and year. This will return all records within the date range.
Is this what you require?
WHERE CAST(Year AS varchar) + RIGHT(100 + Month, 2) +
RIGHT(100 + COALESCE(NULLIF(Day, 0), 1), 2) BETWEEN ...

Date range in PostgreSQL

When I apply a date range to my query, is there anyway to display the dates used in the date range even if there is no data at those dates?
Suppose I use,
... where date between '1/12/2010' and '31/12/2010' order by date
What I want in my result is to show sum of all amount column until 1/12/2010 on that day even if there is no data for that date and also same for 31/12/2010.
Join with generate_series() to fill in the gaps.
Example:
CREATE TEMP TABLE foo AS SELECT CURRENT_DATE AS today;
SELECT
COUNT(foo.*),
generate_series::date
FROM
foo
RIGHT JOIN generate_series('2010-12-18', '2010-12-25', interval '1 day') ON generate_series = today
GROUP BY
generate_series;
Result:
0,'2010-12-18'
0,'2010-12-19'
1,'2010-12-20'
0,'2010-12-21'
0,'2010-12-22'
0,'2010-12-23'
0,'2010-12-24'
0,'2010-12-25'