My SQL table looks like this:
IN_Time Day Name
21:00 Monday Adam781;
22:15 Tuesday Adam952;
23:45 Friday Adam253;
...
I want the query to return the name if {current day && current time} matches Day and In_time column.
e.g So if today is Tuesday and time is 22:15(irrespective of date), query should return Adam952
Below is what I tried, but can't figure out how to add Day as well
SELECT Name FROM test_table
WHERE In_Time IN (SELECT CONVERT(VARCHAR(5), GETDATE(), 108)+':00');
Also, please let me know if there is a better way to select current time(in hh:mm).
You can use:
SELECT Name
FROM test_table
WHERE DAY = DATENAME(weekday, GETDATE()) AND
INTIME = CONVERT(TIME, GETDATE())
Note that this answers your question, but the time needs to match exactly. If you just want the hours and minutes to match:
SELECT Name
FROM test_table
WHERE DAY = DATENAME(weekday, GETDATE()) AND
DATEPART(HOUR, INTIME) = DATEPART(HOUR, GETDATE()) AND
DATEPART(MINUTE, INTIME) = DATEPART(MINUTE, GETDATE())
You also need to compare [day] column with today.
SELECT Name
FROM [test_table]
WHERE IN_Time = CONVERT(varchar(8),getdate(),8)
and [day] = datename(weekday,getdate());
Related
The below query returns MINUTE of certain hour of a date.
For example if date value ='2017-07-19 05:50:00.000', it will returns 50.
My issue is I need to get MINUTE in specified date not all the dates that exist in the table.
Query:
SELECT
DATEPART(MINUTE, ClockOut)
FROM
[dbo].[Attendance]
WHERE
DATEPART(HOUR, ClockOut) = '5'
The query I tried to return minutes only in '2017-07-19' and it returns no record.
SELECT
DATEPART(MINUTE, ClockOut)
FROM
[dbo].[Attendance]
WHERE
DATEPART(HOUR, ClockOut) = '5' AND ClockOut = '2017-07-19'
Sample data
Clock Out
2017-07-19 05:50:00.000
2017-07-20 05:51:00.000
2017-07-21 05:52:00.000
I need to return minutes at hour 5 only on this date '2017-07-19'
You are comparing datetime to date that's why it is not returning your desired result.
SELECT DATEPART(MINUTE, ClockOut)
FROM [dbo].[Attendance]
WHERE DATEPART(HOUR, ClockOut) = '5'
AND CAST(ClockOut AS DATE) = '2017-07-19';
If you use ClockOut='2017-07-19' it's like write '2017-07-19 0:00:00'. Try to use DataPart (yyyy, Clockout)=2017 and DataPary (MM, Clockout)=7 and DataPart (dd, Clockout)=19
Your ClockOut columns contains a DateTime (2017-07-19 12:03:42) so it's value is never exact equal to a date (2017-07-19). Use a range instead so the Query Plan can use an potential index on Clockout. Casting to a Date or using DatePart rules this out causing longer execution times if the number of rows is large.
SELECT DATEPART(MINUTE, ClockOut)
FROM [dbo].[Attendance]
WHERE DATEPART(HOUR, ClockOut) = 5
AND ClockOut BETWEEN '2017-07-19'
AND '2017-07-20' -- start of next day
working demo
I have a problem that is I am unable to resolve as of now.
I need to get the data of
this day, this week and this month
I have a table reminder where I want to select reminders according to
following parameters.
1. Today
2. This Week
3. This Month
The column rdate having the date format in dd-mm-yyyy which is stored as nvarchar
For example
If I execute this weeks query I should get data starting from this week i.e.
If it is Friday I should get data from starting from Sunday to Saturday of that week
How can I get the data as mentioned above. I have searched a lot on internet but I didn't get the solution?
This is the query I have been trying
SELECT
*
FROM
reminder
WHERE
date > DATE_SUB(GETDATE(), INTERVAL 1 DAY)
ORDER BY
rdate DESC;
Where I'm converting nvarchar to date format.
If it's not possible to change the [date] column's data type to DATE, then you will incur a massive performance penalty when trying to filter by date.
Add computed column to table
We can add a computed column that will store the date in the correct format, and then index it for quick searchiing:
ALTER TABLE reminder
ADD Date_Value AS (CONVERT(DATE, '12-05-2016', 105)) PERSISTED;
-- This should yield superior performance
CREATE NONCLUSTERED INDEX IX_Date_Value ON reminder (Date_Value);
Table-valued function to calculate date range
Now, let's create an inline table-valued function to generate the date range for specific period types:
CREATE FUNCTION [dbo].[tvfn_Get_Date_Range](
#Period_Type VARCHAR(100)
)
RETURNS
TABLE
AS RETURN
(
WITH date_range AS(
SELECT CAST(GETDATE() AS DATE) d
-- This line works correctly if your week starts on Sunday
,CAST(DATEADD(WEEK, DATEDIFF(WEEK, '19050101', GETDATE()), '19050101') AS DATE) AS week_start
,CAST(DATEADD(DAY, - DAY(GETDATE()) + 1, GETDATE()) AS DATE) AS month_start
,CAST(DATEADD(MONTH, 1, DATEADD(DAY, - DAY(GETDATE()), GETDATE())) AS DATE) AS month_end
)
SELECT d AS From_Date
,d AS To_Date
FROM date_range
WHERE #Period_Type = 'DAY'
UNION ALL
SELECT week_start
,DATEADD(DAY, 7, week_start)
FROM date_range
WHERE #Period_Type = 'WEEK'
UNION ALL
SELECT month_start
,month_end
FROM date_range
WHERE #Period_Type = 'MONTH'
)
In the above function, week starts on Sunday. If you need this to be configurable, then take a look at the answer to SET DATEFIRST in FUNCTION.
Fast, simple querying now possible
You can now use the two together using a simple query:
SET #Range VARCHAR(100) = 'WEEK'
SELECT *
FROM reminder
CROSS APPLY [dbo].[tvfn_Get_Date_Range](#Range) dr
WHERE Date_Value BETWEEN dr.Date_From AND dr.Date_To
If you can't change the columns data type to Date (or DateTime), you must convert it to date in the query.
Here is one way to get the data for today, this week and this month:
Get records from today:
SELECT *
FROM reminder
WHERE CONVERT(Date, [date], 105) = CAST(GETDATE() as date)
ORDER BY rdate DESC;
Get records from this week:
SELECT *
FROM reminder
WHERE DATEPART(WEEK, CONVERT(Date, [date], 105)) = DATEPART(WEEK, GETDATE())
AND DATEPART(YEAR, CONVERT(Date, [date], 105)) = DATEPART(YEAR, GETDATE())
ORDER BY rdate DESC;
Get records from this Month:
SELECT *
FROM reminder
WHERE DATEPART(MONTH, CONVERT(Date, [date], 105)) = DATEPART(MONTH, GETDATE())
AND DATEPART(YEAR, CONVERT(Date, [date], 105)) = DATEPART(YEAR, GETDATE())
ORDER BY rdate DESC;
To my knowledge, SQL server internally deals with date format as MM/dd/yyyy.
Usually I prefer to save date as string in SQL table since it's easier for inserting and retrieving.
For example, suppose that the column rdate is defined as follows in your table reminder:
[rdate] nvarchar NULL
Then you can customize the select statement for a week as follows:
"Select R.* From reminder R Where CAST(R.rdate as datetime) between
'03/04/2011' AND '03/11/2011'"
And for 10 days as follows:
"Select R.* From reminder R Where CAST(R.rdate as datetime) between
'03/04/2011' AND '03/14/2011'"
And so on. If this is not what you want, please provide more details about your requirements.
I'm hoping to find a solution for this to automate a report I have. Basically what I'm trying to accomplish here is grabbing a date (first day of previous month, two years ago through last day of previous month current year).
So the date span if running this month would look like this: between 4/1/2013 and 3/31/2015
I have found code to get the date two years ago but I'm not able to also incorporate the month functions... Any help is very much appreciated!
For year I'm using this:
SELECT CONVERT(VARCHAR(25),DATEADD(year,-2,GETDATE()),101)
First day of previous month 2 years ago:
SELECT CONVERT(DATE,dateadd(day, -1, dateadd(day, 1 - day(GETDATE()), GETDATE())))
Last day of last month:
SELECT CONVERT(DATE,DATEADD(month, DATEDIFF(month, 0, DATEADD(year,-2,GETDATE())), 0))
Then just do whatever logic you need with them
Your where clause can look something like this:
where date >= cast(dateadd(year, -2,
dateadd(month, -1, getdate() - day(getdate()) + 1)
) as date) and
date < cast(getdate() - day(getdate()) + 1 as date)
This makes use of the handy convenience that subtracting/adding a number to a datetime is the same as adding a date. The start date says: get the first day of the month, then subtract one month, then subtract two years. This could have been done as dateadd(month, -25, . . .), but I think separating the logic is clearer.
This gives you two dates you are looking for:
SELECT
CAST((DATEADD(yy, -2, DATEADD(d, -1 * DATEPART(dd, getdate()) + 1 , GETDATE() ))) as date) as yourTwoYearsAgoDate,
CAST((DATEADD(d, -1 * DATEPART(dd, GETDATE()), GETDATE())) as date) as yourEndOfLastMonthDate
Given a reference date (e.g. "today"),
declare #today date = '23 April 2015'
The 1st of the month is computed by subtracting 1 less than the day number of the current month:
select first_of_current_month = dateadd(day,1-day(#today),#today)
The last day of the previous month is day 0 of the current month, so to get the last day of the previous month, just subtract the current day number:
select last_of_previous_month = dateadd(day,-day(#today),#today)
Moving two years back is easy:
select two_years_back = dateadd(year,-2, #today )
Putting it all together, this should do you:
declare #today date = '23 April 2015'
select *
first_day_of_current_month = dateadd(day,1-day(#today),#today),
last_day_of_previous_month = dateadd(day, -day(#today),#today) ,
date_from = dateadd(year,-2, dateadd(day,1-day(#today),#today) ) ,
date_thru = dateadd(day, -day(#today),#today)
yielding the expected results:
first_day_of_current_month: 2015-04-01
last_day_of_previous_month: 2015-03-31
date_from : 2013-04-01
date_thru : 2015-03-31
So you should be able to say something like this:
select *
from foo t
where t.transaction_date between dateadd(year,-2, dateadd(day,1-day(#today),#today) )
and dateadd(day, -day(#today),#today)
If you have to deal with datetime values rather than date, its easier to not use between and say something like this:
declare #today date = current_timestamp -- get the current date without a time component
select *
from foo t
where t.transaction_date >= dateadd(year,-2, dateadd(day,1-day(#today),#today) )
and t.transaction_date < dateadd(year, 0, dateadd(day, -day(#today),#today)
[superfluous addition of 0 years added for clarity]
am working with MS SQL express and Ignition SCADA by http://www.inductiveautomation.com/
In the SCADA package you are able to create tags from SQL query's. I am trying to use SQL tags to calculate the average packages per minute in a 30min time frame. I was able to do this with two tags and an expression
SELECT MAX(L8Total)
FROM Slicing_tot
WHERE t_stamp BETWEEN DATEADD(minute, -30, GETDATE()) AND GETDATE()
SELECT MIN(L8Total)
FROM Slicing_tot
WHERE t_stamp BETWEEN DATEADD(minute, -30, GETDATE()) AND GETDATE()
What I would like to do from here is store the expressions value and find the max and average for the last 30 days based on time. But I have no idea how to filter 30days of information at a certain time
IE what was the max packages per minute we had at 10:30 from the last 30 days
IE what was the average packages per minute we had at 11:45 form the last 30 days
Please keep in mind that I am new to SQL
SELECT DATEPART(MINUTE, t_stamp)
,MAX(L8Total)
,MIN(L8Total)
FROM Slicing_tot
WHERE ( CONVERT(DATE, t_stamp) >= CONVERT(DATE, GETDATE() - 30)
AND CONVERT(DATE, t_stamp) <= CONVERT(DATE, GETDATE())
)
AND ( CONVERT(TIME, #variable) >= '22:30'
AND CONVERT(TIME, #variable) <= '23:00'
)
GROUP BY DATEPART(MINUTE, t_stamp)
GETDATE()-30 will get you datetime of today minus 30 days ago. Since you are working with datetime field it is best to convert it to date to make sure that you get correct date range. Use of >= and <= is better than between because you is always clear what you doing. Read #Aaron's blog
than for the second part just convert your datetime column to time to limit to specific range during the day.
The following would select between 10 & 11 AM over those 30 days
SELECT MIN(L8Total)
FROM Slicing_tot
WHERE t_stamp BETWEEN DATEADD(dd, -30, GETDATE()) AND GETDATE()
and Datepart(hh,t_stamp) between 10 and 11
or you could compare the time part of the t_stamp to time
SELECT MIN(L8Total)
FROM Slicing_tot
WHERE t_stamp BETWEEN DATEADD(dd, -30, GETDATE()) AND GETDATE()
and convert(time, t_stamp) between '10:30:00.000' and '10:31:00.000'
which would give you the results between 10:30 and 10:31 inclusive of the end points over the last 30 days.
How to retrieve the data where the dates are between the 1st to the 15th of the month when the system date is between the 1st to the 15th day of the month, and when the system date is between the 16th and the end of the month, it will automatically retrieve the data between the 16th and 30th/31st of the month?
Please help me.
I have this code.
SELECT
CONVERT(VARCHAR(11), DATEADD(DAY, DATEDIFF(DAY, 0, DateTimeIn), 0)) AS [Date],
CONVERT(TIME(0),DateTimeIn) AS [Time In], CONVERT(TIME(0),DateTimeOut) AS [Time Out],
Late, Undertime, AWOL, Leave
FROM
tblAttendance2
WHERE
UserID = (SELECT UserID FROM tblUsers WHERE Username = #Username)
AND MONTH(DateTimeIn) = MONTH(GetDate())
ORDER BY
CONVERT(DATE, DateTimeIn, 101) ASC
This shows the data of the whole current month.
Thanks!
You can rely on integer maths to work it out quite straightforwardly:
WHERE
UserID = (SELECT UserID FROM tblUsers WHERE Username = #Username)
AND DATEPART(month,DateTimeIn) = DATEPART(month,GetDate())
AND DATEPART(day,DateTimeIn)/16 = DATEPART(day,GetDate())/16
Basically, any number from 0-15, when divided by 16 will produce the value 0. Any number from 16-31 when divided by 16 will produce the value 1.
(I also switched to DATEPART because I'm a snob because that's how I wrote the day code before I integrated it into your query, and because I like the consistency of this method - in that it can be applied to retrieve any datetime portion, whereas MONTH has counterparts in DAY and YEAR but there are no similar functions to retrieve e.g. the hour)
Sybase solution (for other DBMS, check the "datepart" function equivalend, should be the same in MSSQL.
SELECT
CONVERT(VARCHAR(11), DATEADD(DAY, DATEDIFF(DAY, 0, DateTimeIn), 0)) AS [Date],
CONVERT(TIME(0),DateTimeIn) AS [Time In], CONVERT(TIME(0),DateTimeOut) AS [Time Out],
Late, Undertime, AWOL, Leave
FROM
tblAttendance2
WHERE
UserID = (SELECT UserID FROM tblUsers WHERE Username = #Username)
AND MONTH(DateTimeIn) = MONTH(GetDate())
AND
(
(datepart(day, GetDate() <= 15 AND datepart(day, DateTimeIn) <= 15)
OR
(datepart(day, GetDate() > 15 AND datepart(day, DateTimeIn) > 15)
)
ORDER BY
CONVERT(DATE, DateTimeIn, 101) ASC
Basically the same than other solution, but more self-speaking (in my opinion...).