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.
Related
I want to select day after tomorrow date in sql. Like I want to make a query which select date after two days. If I select today's date from calender(29-04-2015) then it should show date on other textbox as (01-05-2015). I want a query which retrieve day after tomorrow date. So far I have done in query is below:
SELECT VALUE_DATE FROM DLG_DEAL WHERE VALUE_DATE = GETDATE()+2
thanks in advance
Note that if you have a date field containing the time information, you will need to truncate the date part using DATEADD
dateadd(d, 0, datediff(d, 0, VALUE_DATE))
To compare 2 dates ignoring the date part you could just use DATEDIFF
SELECT VALUE_DATE FROM DLG_DEAL
WHERE datediff(d, VALUE_DATE, getdate()) = -2
or
SELECT VALUE_DATE FROM DLG_DEAL
WHERE datediff(d, getdate(), VALUE_DATE) = 2
Try like this:
SELECT VALUE_DATE
FROM DLG_DEAL WHERE VALUE_DATE = convert(varchar(11),(Getdate()+2),105)
SQL FIDDLE DEMO
SELECT VALUE_DATE FROM DLG_DEAL WHERE datediff(d, VALUE_DATE, getdate()) = -2
** I think you should try this**
SELECT DATEADD(day,2,VALUE_DATE) AS DayAfterTomorrow
FROM DLG_DEAL WHERE VALUE_DATE= GETDATE();
DATEADD(choiceToAdd, interval, date)
This function allows you to add or substract day,month, year,etc from date. In this interval is nothing but numeric value which you want to add or substract.
Script that lists dates and week number of date:
DECLARE #initDate DATE = '2014-01-01';
DECLARE #endDate DATE = '2014-12-31';
WITH dates (date, week)
AS (SELECT #initDate date,
Datepart(ww, #initDate) week
UNION ALL
SELECT Dateadd(ww, 1, t.date),
Datepart(ww, t.date)
FROM dates t
WHERE t.date < #endDate)
SELECT dates.date,
dates.week
FROM dates
The first three rows are:
date: week number
---------- -----------
2014-01-01 1
2014-01-08 1
2014-01-15 2
..... ..
..... ..
I guess it should be 2 for the second row and 3 for the first, isn't it?
Is it some kind of bug in DATEPART? Even if something is depends on first day of the year, first row date differs from second on one week with any settings.
Could you clarify this, please?
It is because of Recursive CTE not because of Datepart.
In the Recursive part of CTE week is still holding the previous week not the new date that generated in recursive part
Try changing your query like this.
DECLARE #initDate DATE = '2014-01-01';
DECLARE #endDate DATE = '2014-12-31';
WITH dates (date, week)
AS (SELECT #initDate date,
Datepart(ww, #initDate) week
UNION ALL
SELECT Dateadd(ww, 1, t.date),
Datepart(ww, Dateadd(ww, 1, t.date))
FROM dates t
WHERE t.date < #endDate)
SELECT dates.date,
dates.week
FROM dates
I am writing a query to give me number of products sold this week, this month and this year (3 separate columns) on a week to date, month to date and year to date scale meaning today for example it will show products sold since monday, since the first of the month and since first of the year and this is to continue with each following week, month and year as time goes, there also are to be 3 other columns with the same logic for last year. What i need is help getting the date query using DATEADD or DATEDIFF (example (DATEADD(minute, -15, GETDATE())).
thank you very much and also i'm using SQL Server 2008
Here is some untested code which could probably be optimized, but should get you going in the right direction. This uses a PIVOT operation to transform your rows into columns.
SELECT WeekCount, MonthCount, YearCount
FROM
(
SELECT ProductId,
CASE
WHEN ProductSoldDate >= DATEADD(dd, 1 - DATEPART(dw, GETDATE()), GETDATE())
THEN 'WeekCount'
WHEN ProductSoldDate >= DATEADD(mm, DATEDIFF(mm,0,GETDATE()), 0)
THEN 'MonthCount'
WHEN ProductSoldDate >= DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0)
THEN 'YearCount'
END as lbl
FROM Products
) ProductSales
PIVOT
(
COUNT(ProductId)
FOR lbl IN ([WeekCount], [MonthCount], [YearCount])
) t
Here is the SQL Fiddle.
Good luck.
Using the DATEADD function
In some circumstances, you might want to add an interval of time to a DATETIME or SMALLDATETIME value or subtract an interval of time. For example, you might need to add or subtract a month from a specific date. You can use the DATEADD function to perform this calculation. The function takes the following syntax:
DATEADD(date/time_part, number, date)
Example:
SELECT OrderDate, DATEADD(mm, 3, OrderDate) AS NewDate
FROM Sales.Orders
WHERE OrderID = 1001
Using the DATEDIFF function
The DATEDIFF function calculates the time interval between two dates and returns an integer that represents the interval. The function takes the following syntax:
DATEDIFF(date/time_part, start_date, end_date)
Example:
SELECT OrderDate, DelivDate,
DATEDIFF(hh, OrderDate, DelivDate) AS HoursDiff
FROM Sales.Orders
WHERE OrderID = 1002
Is there a way to use the Now() function in SQL to select values with today's date?
I was under the impression Now() would contain the time as well as date, but today's date would have the time set to 00:00:00 and therefore this would never match?
OK, lets do this properly. Select dates matching today, using indexes if available, with all the different date/time types present.
The principle here is the same in each case. We grab rows where the date column is on or after the most recent midnight (today's date with time 00:00:00), and before the next midnight (tomorrow's date with time 00:00:00, but excluding anything with that exact value).
For pure date types, we can do a simple comparison with today's date.
To keep things nice and fast, we're explicitly avoiding doing any manipulation on the dates stored in the DB (the LHS of the where clause in all the examples below). This would potentially trigger a full table scan as the date would have to be computed for every comparison. (This behaviour appears to vary by DBMS, YMMV).
MS SQL Server: (SQL Fiddle | db<>fiddle)
First, using DATE
select * from dates
where dte = CAST(CURRENT_TIMESTAMP AS DATE)
;
Now with DATETIME:
select * from datetimes
where dtm >= CAST(CURRENT_TIMESTAMP AS DATE)
and dtm < DATEADD(DD, 1, CAST(CURRENT_TIMESTAMP AS DATE))
;
Lastly with DATETIME2:
select * from datetimes2
where dtm2 >= CAST(CURRENT_TIMESTAMP AS DATE)
and dtm2 < DATEADD(DD, 1, CAST(CURRENT_TIMESTAMP AS DATE))
;
MySQL: (SQL Fiddle | db<>fiddle)
Using DATE:
select * from dates
where dte = cast(now() as date)
;
Using DATETIME:
select * from datetimes
where dtm >= cast((now()) as date)
and dtm < cast((now() + interval 1 day) as date)
;
PostgreSQL: (SQL Fiddle | db<>fiddle)
Using DATE:
select * from dates
where dte = current_date
;
Using TIMESTAMP WITHOUT TIME ZONE:
select * from timestamps
where ts >= 'today'
and ts < 'tomorrow'
;
Oracle: (SQL Fiddle)
Using DATE:
select to_char(dte, 'YYYY-MM-DD HH24:MI:SS') dte
from dates
where dte >= trunc(current_date)
and dte < trunc(current_date) + 1
;
Using TIMESTAMP:
select to_char(ts, 'YYYY-MM-DD HH24:MI:SS') ts
from timestamps
where ts >= trunc(current_date)
and ts < trunc(current_date) + 1
;
SQLite: (SQL Fiddle)
Using date strings:
select * from dates
where dte = (select date('now'))
;
Using date and time strings:
select dtm from datetimes
where dtm >= datetime(date('now'))
and dtm < datetime(date('now', '+1 day'))
;
Using unix timestamps:
select datetime(dtm, 'unixepoch', 'localtime') from datetimes
where dtm >= strftime('%s', date('now'))
and dtm < strftime('%s', date('now', '+1 day'))
;
Backup of SQL Fiddle code
There is no native Now() function in SQL Server so you should use:
select GETDATE() --2012-05-01 10:14:13.403
you can get day, month and year separately by doing:
select DAY(getdate()) --1
select month(getdate()) --5
select year(getdate()) --2012
if you are on sql server 2008, there is the DATE date time which has only the date part, not the time:
select cast (GETDATE() as DATE) --2012-05-01
Not sure what your asking!
However
SELECT GETDATE()
Will get you the current date and time
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))
Will get you just the date with time set to 00:00:00
Just zero off the time element of the date. e.g.
SELECT DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)
I've used GetDate as that's an MSSQL function, as you've tagged, but Now() is probably MySQL or you're using the ODBC function call, still should work if you just replace one with the other.
Not sure exactly what you're trying to do, but it sounds like GETDATE() is what you're after. GETDATE() returns a datetime, but if you're not interested in the time component then you can cast to a date.
SELECT GETDATE()
SELECT CAST(GETDATE() AS DATE)
Building on the previous answers, please note an important point, you also need to manipulate your table column to ensure it does not contain the time fragment of the datetime datatype.
Below is a small sample script demonstrating the above:
select getdate()
--2012-05-01 12:06:51.413
select cast(getdate() as date)
--2012-05-01
--we're using sysobjects for the example
create table test (id int)
select * from sysobjects where cast(crdate as date) = cast(getdate() as date)
--resultset contains only objects created today
drop table test
I hope this helps.
EDIT:
Following #dwurf comment (thanks) about the effect the above example may have on performance, I would like to suggest the following instead.
We create a date range between today at midnight (start of day) and the last millisecond of the day (SQL server count up to .997, that's why I'm reducing 3 milliseconds). In this manner we avoid manipulating the left side and avoid the performance impact.
select getdate()
--2012-05-01 12:06:51.413
select dateadd(millisecond, -3, cast(cast(getdate()+1 as date) as datetime))
--2012-05-01 23:59:59.997
select cast(getdate() as date)
--2012-05-01
create table test (id int)
select * from sysobjects where crdate between cast(getdate() as date) and dateadd(millisecond, -3, cast(cast(getdate()+1 as date) as datetime))
--resultset contains only objects created today
drop table test
If you have a table with just a stored date (no time) and want to get those by "now", then you can do this:
SELECT * FROM tbl WHERE DATEDIFF(d, yourdate, GETDATE())=0
This results in rows which day difference is 0 (so today).
For me the query that is working, if I want to compare with DrawDate for example is:
CAST(DrawDate AS DATE) = CAST (GETDATE() as DATE)
This is comparing results with today's date.
or the whole query:
SELECT TOP (1000) *
FROM test
where DrawName != 'NULL' and CAST(DrawDate AS DATE) = CAST (GETDATE() as DATE)
order by id desc
You can try this sql code;
SELECT [column_1], [column_1], ...
FROM (your_table)
where date_format(record_date, '%e%c%Y') = date_format(now(), '%e%c%Y')
You can try:
WHERE created_date BETWEEN CURRENT_TIMESTAMP-180 AND CURRENT_TIMESTAMP
This worked for me:
SELECT * FROM table where date(column_date) = curdate()
For example,
the start date = '20100530' and
the end date = '20100602'
How can I write a SQL to display the below result?
month: may, 2 days
month: June, 2 days
Use a recursive CTE to generate all of the dates between the start and end, and then do a simple group and count (caution, not tested, but should be close if not exactly right):
with dates (the_date) as (
select #start_date
UNION ALL
select dateadd(dd, 1, the_date) from dates where the_date <= #end_date
)
select
datepart(mm, the_date) month,
count(*) num_days
from
dates
group by
datepart(mm, the_date)
TBH, you really need to provide more schema and information about the source data. However, given what little we know, you should be able to write:
Select DateName('month', [Date]) As Month
, Cast(DateDiff(d, #StartDate, #EndDate) As varchar(10) - 1) + ' days'
From Table
Where [Date] Between #StartDate And #EndDate
What we'd need to know to refine our solutions is exactly how 2 days is supposed to be calculated. Is it the days between the start and end date? Is it the day of the second parameter?