Select Date query in SQL - sql-server

i have a date column now i want to write "S" when there is sunday like if i have data like this
datecolumn
1-1-2017
2-1-2017
3-1-2017
4-1-2017
5-1-2017
6-1-2017
7-1-2017
8-1-2017
9-1-2017
10-1-2017
11-1-2017
12-1-2017
13-1-2017
in this if on date there is Sunday day then how to write "Sun" instead on date like this
select datecolumn from table1
datecolumn
1-1-2017
2-1-2017
3-1-2017
Sun
5-1-2017
6-1-2017
7-1-2017
8-1-2017
9-1-2017
10-1-2017
Sun
12-1-2017
13-1-017

If you are using SQL Server 2012+, using IIF Statement.
select
IIF(DATEPART(DW, DateVal) = 1, 'Sun', Convert(varchar(12), datecolumn, 103)) AS datecolumn
from tableName

Try something like this:
SELECT CASE WHEN DATEPART(DW, datecolumn) = 1 THEN 'Sun' ELSE CAST(datecolumn AS NVARCHAR(MAX)) END AS datecolumn
FROM table1
Hope it helps.
PS - might have to modify the CAST(datecolumn AS NVARCHAR(MAX)) to a CONVERT if you need the dates in a specific date format.

Related

How to convert date format yyyymmdd to yyyy/mm/dd in SQL Server 2008

I tried some conversions but seems like it's not working. My datatype is a decimal:
date_column
-----------
20140619
20160527
20150601
20131127
20170217
20171204
20160519
My SQL statement:
SELECT
CONVERT(DATE, CONVERT(VARCHAR(10), date_column), 111) AS mydate
FROM
my_table
Results
mydate
-------------
2014-06-19
2016-05-27
2015-06-01
2013-11-27
2017-02-17
2017-12-04
2016-05-19
You currently do this:
decimal -> varchar -> date
which is good, but you are still missing one more step:
decimal -> varchar -> date -> varchar (new format)
Thus, you need:
select CONVERT(varchar(10), CONVERT(date, CONVERT(varchar(8), date_column)), 111) as mydate
from my_table
(What you should actually do is to store the date as a DATE in the first place, but I am aware that this is not always an option for legacy databases.)
You can try either of the below code, based on your preference.
POST SQL SERVER 2012
declare #testDate DATE;
SET #testDate = '20140619'
SELECT FORMAT ( #testDate, 'd', 'zh-cn' ), FORMAT( #testDate, 'yyyy/MM/dd', 'en-US' )
Prior to SQL SERVER 2012
declare #testDate DATE;
SET #testDate = '20140619'
SELECT REPLACE(CAST(CONVERT(date,'20140619',111) AS CHAR(10),'-','/')
SELECT convert(char(10),#testDate,111)
Let me share some of the answers i got:
select format(cast(date_column as date),'yyyy/MM/dd') as mydate
from my_table;
select convert(date,convert(varchar(10), date_column ), 111 ) as mydate
from my_table;
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/53a51068-b802-43e7-baa3-7510d56c5b63/how-to-convert-date-formart-yyyymmdd-to-yyyymmdd-in-sql-server-2008?forum=transactsql
Thank you

Check if date falls within Month and Year range

If a user selects a range such as:
Start: November 2016
End: September 2017,
I want to include all results that fall within the range of 2016-11-01 to 2017-09-30.
I tried concatenating together the year, month, and day, however the issue comes that not all months have the same last day. While I know all months start on day 01, a month's end day can be 28, 29, 30, or 31.
Is there a way to do this without constructing the date? SqlServer 2008 doesn't have the EOMONTH function, and I feel like anything more complex than that is not the right solution. I would like to avoid this:
WHERE
DateCol >= '2016' + '-' + '11' + '-01' AND
DateCol <= '2017' + '-' + '09' + '-30'
It really seems to me that the easiest and best answer is to go from the first of the beginning month to the first of the month after the ending month, and make the second comparison not inclusive.
In other words, instead of this:
WHERE
DateCol >= '2016' + '-' + '11' + '-01' AND
DateCol <= '2017' + '-' + '09' + '-30'
simply this:
WHERE
DateCol >= '2016' + '-' + '11' + '-01' AND
DateCol < '2017' + '-' + '10' + '-01'
There is a faster way to do so :
DECLARE #minDate DATE
DECLARE #maxDate DATE
SET #minDate = XXXXX
SET #maxDate = YYYYY
-- Get the first day of the month minDate.
SET #minDate = CONVERT(datetime,CONVERT(varchar(6),#minDate,112)+'01',112)
-- Get the last day of the month minDate.
SET #maxDate = CONVERT(datetime,CONVERT(varchar(6),#maxDate,112)+'01',112)
SET #maxDate = DATEADD(day, -1, DATEADD(month, 1, #maxDate))
SELECT * FROM myTABLE WHERE DateCol >= #minDate AND DateCol <= #maxDate
Or :
SELECT * FROM myTABLE
WHERE DateCol >= CONVERT(datetime,CONVERT(varchar(6),XXXXX,112)+'01',112)
AND DateCol <= DATEADD(day, -1, DATEADD(month, 1, CONVERT(datetime,CONVERT(varchar(6),YYYYY,112)+'01',112)))
Use syntax like CONVERT(datetime,'20170930',112) or CONVERT(datetime,'09-30-2017',110) for XXXXX and YYYYY rather than '2017-09-30' that use SQL Server implicit convertion from char to datetime (rely on the server configuration : can be hazardous!!!)).
Using this syntax is faster because #minDate and #maxDate do not need any evaluation. So that indexes can be used directly...
Otherwise a scalar function that will simulate the eomonth() behaviour could be usefull...
You could use following select statement to get last date of any month (and any year) by passing a field or date to it:
DECLARE #dtDate DATE
SET #dtDate = '09/25/2016'
SELECT CAST(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#dtDate)+1,0)) AS DATE) AS LastDay_AnyMonth
Please provide some example data and desired result and I will update my answer further.
Here you go:
DECLARE #YourTable TABLE (YourData DATE);
INSERT INTO #YourTable VALUES
('2016-11-01'),
('2016-09-05'),
('2017-03-03'),
('2017-11-11'),
('2017-12-14'),
('2017-09-30');
WITH CTE AS (
SELECT YourData
FROM #YourTable
WHERE YEAR(YourData) =2016 AND MONTH (YourData) >= 11
)
SELECT YourData
FROM #YourTable
WHERE YEAR(YourData) =2017 AND MONTH (YourData) <= 9
UNION ALL
SELECT YourData
FROM CTE;
There is no need to know the end of the month (28 or 30 or 31).
For 2008, you can simply convert the string
Example
Select Date1=convert(date,'November 2016')
,Date2=dateadd(DAY,-1,dateadd(MONTH,1,convert(date,'September 2017')))
Returns
Date1 Date2
2016-11-01 2017-09-30
So the WHERE would be somthing like this
...
Where DateCol between convert(date,'November 2016')
and dateadd(DAY,-1,dateadd(MONTH,1,convert(date,'September 2017')))
A useful construct for performing date-based operations is to make use of a Date Dimension table. You are creating a lookup table that is populated with a lot of information about dates over a large span of time. You can then query the table based on the information that you do have. The table is small enough so that it does not impose significant performance concerns.
In your particular case, you have the month and year. You would plug that into the date dimension table to get the first of the month from the beginning month and the last of the month from the ending month. You now have a time range to search over without any complex logic or calculations on the fly.
Aaron Bertrand explains it in depth here: https://www.mssqltips.com/sqlservertip/4054/creating-a-date-dimension-or-calendar-table-in-sql-server/

Populate a column in SQL Server by weekday or weekend depending on the datetime

I am working on SQL Server, wherein I cannot update any existing column nor can I add any more data/ column to the data.
I have a column of dttime (yyyy-mm-dd hh:mm:ss) which consists of the date time value against each entry.
I want to select the existing columns , and a new column as wd which will be populated as 'weekend' when the day of the week is either Saturday or Sunday and 'weekday' in case of other days
I am using the below query:
SELECT id, total,
case when dayofweek(dttime) in (1,7) then 'Weekend' else 'Weekday' end as wd
from table_name
Please suggest where is the mistake here, or is there any alternative to this, in case I have more than two different things to populate in a similar way, based on another column.
You can use DATENAME of dw or weekday to achieve your expectation:
SELECT id, total,
CASE WHEN DATENAME (dw, dttime) IN ('Saturday', 'Sunday') THEN 'Weekend'
ELSE 'Weekday' END AS wd
FROM table_name
Also your first day of the week can be set by the SET DATEFIRST, so based on the DATEFIRST set value the integer value for Sunday and Saturday can change. So getting DATENAME for the dttime will not cause any confusion.
You can execute the below query to understand more in detail, DATENAME will always return the current day name, but DATEPART will return based on the DATEFIRST.
SELECT ##DATEFIRST AS 'First Day',
DATEPART(dw, GETDATE()) AS 'Today',
DATENAME(dw, GETDATE()) AS 'TodayName';
If SELECT ##DATEFIRST returns 7, then you can use
CASE WHEN DATEPART(dw, dttime) IN (1, 7) THEN 'Weekend' ELSE 'Weekday' END AS wd
Here 1 for Sunday and 7 for Saturday.
You need DATEPART function. try this :
SELECT id, total,
case when DATEPART(dw,dttime) in (6,7) then 'Weekend' else 'Weekday' end as wd
from table_name
Please try below query
SELECT id, total,
case when DATEPART(dw,dttime) in (1,7) then 'Weekend' else 'Weekday' end as wd
from table_name

How to create stored procedure for alternative working Saturdays?

I want to create a stored procedure for displaying working Saturdays.
For example:
Last working Saturday 08/08/2015 (dd/mm/yyyy), then next working Saturday should be 22/08/2015 (dd/mm/yyyy)
It should omit between Saturday (15/08/2015). Likewise, I want to show for particular year
Try this. The assumption is, 3rd Jan 2015 was the first working Saturday.
DECLARE #firstsaturday date = '2015-01-03'
;WITH CTE AS
(
SELECT #firstsaturday AS StartDate
UNION ALL
SELECT DATEADD(WK,2,StartDate)
FROM CTE
WHERE YEAR(StartDate) = '2015'
)
SELECT * FROM CTE
WHERE YEAR(StartDate) = '2015'
Try something like this
DECLARE #start_sat_day DATE = Dateadd(d, -( Datepart(dw, Getdate()) % 7 ), Getdate());
WITH cte
AS (SELECT #start_sat_day AS sat_days
UNION ALL
SELECT Dateadd(dd, 14, sat_days)
FROM cte
WHERE Year(sat_days) = Year(#start_sat_day))
SELECT sat_days
FROM cte
WHERE Year(sat_days) = Year(#start_sat_day)
Result :
sat_days
---------
2015-08-08
2015-08-22
2015-09-05
2015-09-19
2015-10-03
2015-10-17
2015-10-31
2015-11-14
2015-11-28
2015-12-12
2015-12-26

SQL Server remove milliseconds from datetime

select *
from table
where date > '2010-07-20 03:21:52'
which I would expect to not give me any results... EXCEPT I'm getting a record with a datetime of 2010-07-20 03:21:52.577
how can I make the query ignore milliseconds?
You just have to figure out the millisecond part of the date and subtract it out before comparison, like this:
select *
from table
where DATEADD(ms, -DATEPART(ms, date), date) > '2010-07-20 03:21:52'
If you are using SQL Server (starting with 2008), choose one of this:
CONVERT(DATETIME2(0), YourDateField)
LEFT(RTRIM(CONVERT(DATETIMEOFFSET, YourDateField)), 19)
CONVERT(DATETIMEOFFSET(0), YourDateField) -- with the addition of a time zone offset
Try:
SELECT *
FROM table
WHERE datetime >
CONVERT(DATETIME,
CONVERT(VARCHAR(20),
CONVERT(DATETIME, '2010-07-20 03:21:52'), 120))
Or if your date is an actual datetime value:
DECLARE #date DATETIME
SET #date = GETDATE()
SELECT CONVERT(DATETIME, CONVERT(VARCHAR(20), #date, 120))
The conversion to style 120 cuts off the milliseconds...
select * from table
where DATEADD(ms, DATEDIFF(ms, '20000101', date), '20000101') > '2010-07-20 03:21:52'
You'll have to trim milliseconds before comparison, which will be slow over many rows
Do one of these to fix this:
created a computed column with the expressions above to compare against
remove milliseconds on insert/update to avoid the read overhead
If SQL Server 2008, use datetime2(0)
Use CAST with following parameters:
Date
select Cast('2017-10-11 14:38:50.540' as date)
Output: 2017-10-11
Datetime
select Cast('2017-10-11 14:38:50.540' as datetime)
Output: 2017-10-11 14:38:50.540
SmallDatetime
select Cast('2017-10-11 14:38:50.540' as smalldatetime)
Output: 2017-10-11 14:39:00
Note this method rounds to whole minutes (so you lose the seconds as well as the milliseconds)
DatetimeOffset
select Cast('2017-10-11 14:38:50.540' as datetimeoffset)
Output: 2017-10-11 14:38:50.5400000 +00:00
Datetime2
select Cast('2017-10-11 14:38:50.540' as datetime2)
Output: 2017-10-11 14:38:50.5400000
For this particular query, why make expensive function calls for each row when you could just ask for values starting at the next higher second:
select *
from table
where date >= '2010-07-20 03:21:53'
Use 'Smalldatetime' data type
select convert(smalldatetime, getdate())
will fetch
2015-01-08 15:27:00
There's more than one way to do it:
select 1 where datediff(second, '2010-07-20 03:21:52', '2010-07-20 03:21:52.577') >= 0
or
select *
from table
where datediff(second, '2010-07-20 03:21:52', date) >= 0
one less function call, but you have to be beware of overflowing the max integer if the dates are too far apart.
One more way I've set up SQL Server queries to ignore milliseconds when I'm looking for events from a particular second (in a parameter in "YYYY-MM-DD HH:TT:SS" format) using a stored procedure:
WHERE
...[Time_stamp] >= CAST(CONCAT(#YYYYMMDDHHTTSS,'.000') as DateTime) AND
...[Time_stamp] <= CAST(CONCAT(#YYYYMMDDHHTTSS,'.999') as DateTime)
You could use something similar to ignore minutes and seconds too.
Please try this
select substring('12:20:19.8470000',1,(CHARINDEX('.','12:20:19.8470000',1)-1))
(No column name)
12:20:19
I'm very late but I had the same issue a few days ago. None of the solutions above worked or seemed fit. I just needed a timestamp without milliseconds so I converted to a string using Date_Format and then back to a date with Str_To_Date:
STR_TO_DATE(DATE_FORMAT(your-timestamp-here, '%Y-%m-%d %H:%i:%s'),'%Y-%m-%d %H:%i:%s')
Its a little messy but works like a charm.
May be this will help..
SELECT [Datetime] = CAST('20120228' AS smalldatetime)
o/p:
2012-02-28 00:00:00
Review this example:
declare #now datetimeoffset = sysdatetimeoffset();
select #now;
-- 1
select convert(datetimeoffset(0), #now, 120);
-- 2
select convert(datetimeoffset, convert(varchar, #now, 120));
which yields output like the following:
2021-07-30 09:21:37.7000000 +00:00
-- 1
2021-07-30 09:21:38 +00:00
-- 2
2021-07-30 09:21:37.0000000 +00:00
Note that for (1), the result is rounded (up in this case), while for (2) it is truncated.
Therefore, if you want to truncate the milliseconds off a date(time)-type value as per the question, you must use:
declare #myDateTimeValue = <date-time-value>
select cast(convert(varchar, #myDateValue, 120) as <same-type-as-#myDateTimeValue>);

Resources