Get last 2 weeks data (full week) - sql-server

I need to run a script that pulls existing data for the last 2 weeks (full weeks Sun-Sat) irrespective of when I run it.
This does not work as it's subtracting the number of days instead of the week giving incorrect data.
Select
convert(varchar(255), cast(cast(Date as varchar(255)) as date), 101) as Date, ID
From Table
where convert(varchar(255), cast(cast(date_key as varchar(255)) as date), 101)>=DATEADD(week,-3,GETDATE())

SELECT
convert(varchar(255), cast(cast(date_key as varchar(255)) as date), 101)as date_Key
FROM [dbo].[Table]
where datename(week, convert(varchar(255), cast(cast(date_key as varchar(255))as date), 101)) >= datename(week, getdate())-2

You should use the built in function DATEPART(weekday, dateValue) here
https://learn.microsoft.com/en-us/sql/t-sql/functions/datepart-transact-sql?view=sql-server-ver15

Related

SQL Server Date Calculation

I want to get the based on current date.
If current date is:
01st to 14th of any month, it needs to return 15th of that month
15th to 31st of any month, it needs to return last day of that month
For example:
Current_Date Exp_date
-------------------------
01-08-2019 15-08-2019
10-08-2019 15-08-2019
14-08-2019 15-08-2019
15-08-2019 31-08-2019
20-08-2019 31-08-2019
25-08-2019 31-08-2019
31-08-2019 31-08-2019
I want as much as simplified form.
We can achieve it with simple logic as below .
If You are using Sql Server version 2012 and higher versions we've EOMONTH() Function to give EndOfMonth Date .
Sample Data:
CREATE TABLE #YourTable (CurrentDate DATETIME)
INSERT INTO #YourTable (CurrentDate)SELECT '08-01-2019'
INSERT INTO #YourTable (CurrentDate) SELECT '08-10-2019'
INSERT INTO #YourTable (CurrentDate) SELECT '08-14-2019'
INSERT INTO #YourTable (CurrentDate) SELECT '08-15-2019'
INSERT INTO #YourTable (CurrentDate) SELECT '08-20-2019'
INSERT INTO #YourTable (CurrentDate) SELECT '08-25-2019'
INSERT INTO #YourTable (CurrentDate) SELECT '08-31-2019'
Query:
SELECT DATEPART(DD,CurrentDate),
case when DATEPART(DD,CurrentDate)<15 THEN DATEADD(dd,-day(CurrentDate)+15,CurrentDate)
when DATEPART(DD,CurrentDate)>14 THEN EOMONTH(CurrentDate) END AS Exp_Date
FROM #YourTable
You may try this.
select current_date,
case when datepart(day, current_date) > 14
then
DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, current_date) + 1, 0))
else
DATEADD(D, 15, DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, current_date) , 0)))
end as Exp_date
from yourtable
Try this:replace hardCode date With your date
SELECT CONCAT(CONCAT(CONCAT (CONCAT(CASE WHEN DAY('2017/08/25') < 14 THEN 15 else 31 end , '-'),
CASE WHEN DATEPART(month, '2017/08/25') < 10 THEN Concat('0',DATEPART(month, '2017/08/25')) else DATEPART(month, '2017/08/25') end),'-'), cast(DATEPART(year, '2017/08/25') as nvarchar(4)))
SELECT [Current_date],Exp_date,
CASE WHEN 14 BETWEEN DATEPART(DAY,[Current_date]) AND DATEPART(DAY,Exp_date)
THEN CAST(DATEADD(DAY,15-DATEPART(DAY,[Current_date]),[Current_date]) AS DATE)
ELSE CAST(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,[Current_date])+1,0)) AS DATE)
END
FROM MOnthData
Check this..
select case when datepart(dd, dt) between 1 and 14 then right('0'+ cast(month(dt) as varchar(2)), 2) + '-15-' + cast(year(dt) as varchar(4)) else eomonth(dt) end from test

Dynamically set the Start and End time of Day

I have this table in which I am storing TimeIn and Time Out of Employee.
When I get Total Hours any Employee have worked in certain day, it works fine date wise. But in out organization the issue is that a day is considered from 6 AM till 5:59 AM (next day).
Here is my table and sample data.
CREATE TABLE [dbo].[Attendance]
(
[Employee] [varchar](50) NULL,
[TimeIn] [datetime] NULL,
[TimeOut] [datetime] NULL
) ON [PRIMARY]
GO
INSERT [dbo].[Attendance] ([Employee], [TimeIn], [TimeOut]) VALUES (N'Lewis', CAST(N'2018-12-01 06:30:00.000' AS DateTime), CAST(N'2018-12-01 18:22:00.000' AS DateTime))
GO
INSERT [dbo].[Attendance] ([Employee], [TimeIn], [TimeOut]) VALUES (N'Lewis', CAST(N'2018-12-01 20:12:00.000' AS DateTime), CAST(N'2018-12-01 23:50:00.000' AS DateTime))
GO
INSERT [dbo].[Attendance] ([Employee], [TimeIn], [TimeOut]) VALUES (N'Lewis', CAST(N'2018-12-02 00:12:00.000' AS DateTime), CAST(N'2018-12-02 04:50:00.000' AS DateTime))
GO
INSERT [dbo].[Attendance] ([Employee], [TimeIn], [TimeOut]) VALUES (N'Lewis', CAST(N'2018-12-02 07:21:00.000' AS DateTime), CAST(N'2018-12-02 19:54:00.000' AS DateTime))
GO
Here is the query and output of the query I am executing.
SELECT Employee, CAST(COALESCE(TimeIn, TimeOut) AS DATE) DATE, DATEDIFF(HOUR, MIN(TimeIn), MAX(TimeOut)) [Hours Worked]
FROM [dbo].[Attendance]
GROUP BY Employee, CAST(COALESCE(TimeIn, TimeOut) AS DATE)
Output:
Employee DATE Hours Worked
----------------- ---------- ------------
Lewis 2018-12-01 17
Lewis 2018-12-02 19
What I want is to get the working hours calculated from 6 AM to 5:59 AM next day. So the expected output is as below:
Employee DATE Hours Worked
----------------- ---------- ------------
Lewis 2018-12-01 22:20
Lewis 2018-12-02 12:33
Hope this is possible..
You should probably have a calendar table which contains all the dates which you want to appear in your report. In the absence of that, we can just assume that all dates are covered by the time, and we can group by the time in, shifted earlier by 6 hours. The trick here is that we can shift all times backwards by 6 hours, to align everything with the usual 24 hour day. Something like this should work:
SELECT
Employee,
CONVERT(date, DATEADD(HOUR, -6, TimeIn)) AS DATE,
CONVERT(VARCHAR(10), DATEDIFF(HOUR, MIN(TimeIn), MAX(TimeOut))) + ':' +
CONVERT(VARCHAR(10), DATEDIFF(MINUTE, MIN(TimeIn), MAX(TimeOut)) % 60) AS [Hours Worked]
FROM Attendance
GROUP BY
Employee,
CONVERT(date, DATEADD(HOUR, -6, TimeIn));
Demo

Date column won't convert if I use it in the where clause

So I have this code that runs great:
SELECT
QuoteDet.QuoteNo,
Quote.SalesID,
Quote.CustCode,
QuoteDet.PartNo AS [Version],
QuoteDet.Price1 AS [Unit Price],
CONVERT(VARCHAR(30), CAST(QuoteDet.User_Text1 AS DATE), 1) AS [Submittal Date]
FROM QuoteDet INNER JOIN Quote ON QuoteDet.QuoteNo = Quote.QuoteNo
WHERE QuoteDet.Status IN ('Req', 'Pend')
AND QuoteDet.User_Text1 <> 'HOLD'
GROUP BY QuoteDet.QuoteNo, Quote.SalesID, Quote.CustCode, QuoteDet.PartNo,
QuoteDet.Price1, QuoteDet.User_Text1
ORDER BY CONVERT(VARCHAR(30), CAST(QuoteDet.User_Text1 AS DATE), 1)
But when I add the following condition in the where clause to get the current week, I get the message "Conversion failed when converting date and or time from character string
SELECT
QuoteDet.QuoteNo,
Quote.SalesID,
Quote.CustCode,
QuoteDet.PartNo AS [Version],
QuoteDet.Price1 AS [Unit Price],
CONVERT(VARCHAR(30), CAST(QuoteDet.User_Text1 AS DATE), 1) AS [Submittal Date]
FROM QuoteDet INNER JOIN Quote ON QuoteDet.QuoteNo = Quote.QuoteNo
WHERE QuoteDet.Status IN ('Req', 'Pend')
AND CONVERT(VARCHAR(30), CAST(QuoteDet.User_Text1 AS DATE), 1) >=
DATEADD(DAY, 1-DATEPART(dw, GETDATE()), CONVERT(DATE, GETDATE()))
AND CONVERT(VARCHAR(30), CAST(QuoteDet.User_Text1 AS DATE), 1) <
DATEADD(DAY, 8-DATEPART(dw, GETDATE()), CONVERT(DATE, GETDATE()))
AND QuoteDet.User_Text1 <> 'HOLD'
GROUP BY QuoteDet.QuoteNo, Quote.SalesID, Quote.CustCode, QuoteDet.PartNo,
QuoteDet.Price1, QuoteDet.User_Text1
ORDER BY CONVERT(VARCHAR(30), CAST(QuoteDet.User_Text1 AS DATE), 1)
Why don't I get the error in the first query? It's also converting to a date, yet no error
Another possibility, first query works, because the conversion in the select clause happens after the narrowing of rows by the where clause. By moving the convert to the where clause it can now be run on all rows, some of which may have bad data that does not make it through to the select clause in the first query.
If you are on a sufficiently new version of SQL Server, TRY_PARSE will allow conversions without errors by returning NULL for un-convertable strings.
In your first query you are:
first casting the 'QuoteDet.User_Text1' as a Date
then converting the result to a VARCHAR of length 30, resulting in a string
In your second query, you are trying to use a string to check for a date. What you should do in the WHERE clause is to remove the 'Convert' method call, and just use the 'Cast' method. So instead of this:
CONVERT(VARCHAR(30), CAST(QuoteDet.User_Text1 AS DATE), 1)
you have to use the following in your WHERE clause:
CAST(QuoteDet.User_Text1 AS DATE)

how to write a query for this scenario?

I had a query like this,
SELECT
CONVERT(VARCHAR(3), DATENAME(MONTH, date)) + '-' +
RIGHT(DATENAME(YEAR, date), 2) AS date
FROM
tblSample
GROUP BY
CONVERT(VARCHAR(3), DATENAME(MONTH, date)) + '-' +
RIGHT(DATENAME(YEAR, date), 2) AS date
ORDER BY
CONVERT(VARCHAR(3), DATENAME(MONTH, date)) + '-' +
RIGHT(DATENAME(YEAR, date), 2) AS date
I had data like this:
Apr-17
jan-16
jan-17
mar-17
I have a requirement that the output should order by year part which means all the '17' (year parts) data should be shown. Like that we have to use order by for year part only how can I do that?
You have to just change your order by query as below, you include both month name and year in order by instead of just select year in order by clause
ORDER BY RIGHT(DATENAME(YEAR, date), 2) AS date
If you wants to apply order on first year and then month then write query as below:
ORDER BY RIGHT(DATENAME(YEAR, [date]), 2) DESC, CONVERT(VARCHAR(3), DATENAME(MONTH, [date]))
I have tried below data:
DECLARE #tblA AS TABLE(
[date] date
)
INSERT INTO #tblA VALUES('01-Apr-2017')
INSERT INTO #tblA VALUES('01-Jan-2016')
INSERT INTO #tblA VALUES('01-Jan-2017')
INSERT INTO #tblA VALUES('01-Mar-2017')
SELECT
CONVERT(VARCHAR(3), DATENAME(MONTH, [date])) + '-' +
RIGHT(DATENAME(YEAR, [date]), 2) AS date
FROM #tblA ORDER BY YEAR([date]) DESC, MONTH([date])
Output:
select CONVERT(VARCHAR(3),DATENAME(MONTH,date))+'-
'+right(DATENAME(YEAR,date),2) as date from
tblSample
order by YEAR([date]),MONTH([date])
select distinct CONVERT(VARCHAR(3),DATENAME(MONTH,date))+'-'+right(DATENAME(‌​
YEAR,date),2) as date,YEAR([date]) as year,MONTH([date]) as month from
tblSample order by YEAR([date]) desc,MONTH([date])

Counting occurrences over all dates (not a specific date)

I have this piece of code that counts the number of occurrences for a set of events on an hourly basis. I have it set up to calculate the count for all the hours where locate_received_date is 2016-12-01 (Note: locate_received_date data type is DATETIME with YYYY-MM-DD hh:mm:ss format). I entered the date manually to count for the previous day. The code excerpt is below:
SELECT CAST(locate_received_date as date) AS 'ForDate',
DATEPART(hh, locate_received_date) AS 'OnHour',
COUNT (*) AS 'HourCount'
FROM MyTable
WHERE locate_received_date BETWEEN '2016-12-01 00:00:00.000' AND '2016-12-01 23:59:59.999'
GROUP BY CAST(locate_received_date as date), DATEPART(hh, locate_received_date);
Now the table "MyTable" has hundreds of rows worth of data for many different dates. I need to run the count for all distinct dates, not just manually entered specific ones. I was thinking I could nest the following somehow:
DISTINCT CAST(locate_received_date AS DATE)
Or perhaps do this using some kind of a FOR loop?
EDIT:
Here's the script to create the table. There really isn't any other column worth creating. There is no ID or anything in the table. The table is being updated and every time there is an update, locate_received_date is update with the date and time of occurrence. I need to count first based on hours (which my script does), and also based on days.
CREATE Table myTable(
Locate_Received_Date date);
INSERT INTO myTable(Locate_Received_Date) VALUES ('2016-12-01 15:14:07.000');
INSERT INTO myTable(Locate_Received_Date) VALUES ('2016-12-01 15:13:37.000');
INSERT INTO myTable(Locate_Received_Date) VALUES ('2016-12-02 15:13:37.000');
INSERT INTO myTable(Locate_Received_Date) VALUES ('2016-12-01 15:13:07.000');
INSERT INTO myTable(Locate_Received_Date) VALUES ('2016-12-02 15:12:08.000');
INSERT INTO myTable(Locate_Received_Date) VALUES ('2016-12-02 15:12:07.000');
INSERT INTO myTable(Locate_Received_Date) VALUES ('2016-11-28 15:11:37.000');
INSERT INTO myTable(Locate_Received_Date) VALUES ('2016-12-02 15:11:08.000');
INSERT INTO myTable(Locate_Received_Date) VALUES ('2016-12-02 15:11:07.000');
INSERT INTO myTable(Locate_Received_Date) VALUES ('2016-11-28 15:10:37.000');
INSERT INTO myTable(Locate_Received_Date) VALUES ('2016-11-29 15:10:08.000');
Any help will be appreciated. Thanks
The reason it is only counting one day is that the where clause specifies one day. If you remove the where clause and add an order by, I think you will accomplish what you are looking for. Let me know if your desired output differs from what this renders and I can update the query accordingly:
SELECT CAST(locate_received_date as date) AS 'ForDate',
DATEPART(hh, locate_received_date) AS 'OnHour',
COUNT (*) AS 'HourCount'
FROM MyTable
GROUP BY CAST(locate_received_date as date), DATEPART(hh, locate_received_date)
ORDER BY CAST(locate_received_date as date), DATEPART(hh, locate_received_date);
Your locate_received_date is a datetime, not a date, right? If so, then something like this should work:
select count(Locate_Received_Date) from myTable
group by
convert(varchar(10), cast(Locate_Received_Date as date), 112) + '_' +
convert(varchar(2), DATEPART(hh, Locate_Received_Date))
Is it correct that you need to count occurrences for particular day with hour step? If so, then here is synthetic example:
with a as (select convert(datetime,'2016-12-01 00:01:00.000',120) s
union all
select convert(datetime,'2016-12-01 01:02:02.000',120) s
union all
select convert(datetime,'2016-12-01 00:03:03.000',120) s
union all
select convert(datetime,'2016-12-01 03:04:04.000',120) s
union all
select convert(datetime,'2016-12-01 00:05:05.000',120) s
union all
select convert(datetime,'2016-12-01 06:00:00.010',120) s )
,
b as(select convert(varchar(10), s,120) s
, a.s dt
, DATEPART(hh,s)onhour
from a )
select count(*)cnt, s, onhour
from b
group by s, onhour
Applying to your data it would be:
with a as (select convert(varchar(10), locate_received_date,120)s
, locate_received_date
, DATEPART(hh,locate_received_date)onhour
from MyTable
)
select count(*)cnt, s, onhour
from a
group by s, onhour
the main thing you must remember is the MS SQL Server conversion codes according to this: https://msdn.microsoft.com/en-us/library/ms187928.aspx

Resources