SQL get Monthly, and weekly data - sql

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

Related

Add week number column in query results from existing date column

The current query is shown below and I am struggling with trying to add a column to my results query, where it converts the PRODUCTION_DATE into fiscal week.
SELECT
ORDER_QTY, SKU, INVOICE_NUMBER, CUSTOMER_NUMBER, ROUTE,
ALLOCATED_QTY, SHORTED_QTY, PRODUCTION_DATE
FROM
[DATEBASE_NAME].[XYZ].[ORDERS]
WHERE
[PRODUCTION_DATE] >= DATEADD(day, -300, GETDATE())
AND [PRODUCTION_DATE] <= GETDATE()
I believe DATEPART is part of the function, I just don't know how to execute. End goal would be a column in the results that just returns the fiscal week along with all other data. The little query above returns my data proper now, I am just trying to get that column in.
Thanks for looking.
As you have already mentioned about DATEPART;
(And you were almost there !!)
Here is the modified query
SELECT
ORDER_QTY, SKU, INVOICE_NUMBER, CUSTOMER_NUMBER, ROUTE,
ALLOCATED_QTY, SHORTED_QTY, PRODUCTION_DATE,
DATEPART(wk, PRODUCTION_DATE) AS FISCAL_WEEK
FROM
[DATEBASE_NAME].[XYZ].[ORDERS]
WHERE
[PRODUCTION_DATE] >= DATEADD(day, -300, GETDATE())
AND [PRODUCTION_DATE] <= GETDATE();

SQL Select Records based on current date minus two days

I have an orders table which contains an order ID, order date and order description.
I want to run a select query which captures all orders that have been created in the last two days. so the current date minus two days. from the 14th December, I would want to select all orders where the order date is > 13th December. This needs to use a Get date function to pick up the current date and minus the days.
I have tried:
select * from orders where orderdate > getdate() - 2
but this is not producing the correct results. Any idea's how to do this please?
you should try to use dateadd function
select * from orders where orderdate > dateadd(dd,-1,cast(getdate() as date))
Now, this may be exactly what you need but then you need to understand that by casting to date we remove the time part and effectively go back to the start of the day and a day behind it(-1) gives the start of yesterday.
Try this:
select * from orders where orderdate > cast(getdate() - 1 as date)
If you want the orders of the last two days, use DATEADD to add days to today's date (in your case -2 days) then use DATEDIFF to compare the two days:
SELECT * FROM orders
WHERE DATEDIFF(DAY, DATEADD(DAY, -2, GETDATE()), orderdate) > 0
Now, assuming all orders have dates in the past and none in the future (which is what it should be), you can simply use DATEDIFF like this:
SELECT * FROM orders
WHERE DATEDIFF(DAY, orderdate, GETDATE()) <= 2
Note: you can use < 3 instead of <= 2.
Looks like dateadd and convert will solve the problem.
select o.*
from orders o
where o.orderdate >= dateadd(day, -2, convert(date, getdate()))

How to select data's from this today,week and month sperately?

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.

SQL getdate issue with month

i need help on my little problem.
SELECT FORMAT(ServiceDate, 'dd-MM-yyy") AS ServiceDate
FROM Services
WHERE Day(ServiceDate) BETWEEN '1' AND Day(getdate() -2)
AND Month(ServiceDate) =
CASE
WHEN Day(getdate()) <=2
THEN Month(getdate() -1
ELSE Month(getdate())
END
AND Year(ServiceDate) = Year(getdate())
Now the problem is the first and the second of the Month.
The query don't use the last month. It shows the actual month.
I hope its clear what i need.
if we have the 01-06-2016 and i need minus 2, so the query must give me back to the day 30-05-2016
big THX
the output for today with this query
output query
Assuming you are using sql-server, you need to use DATEADD(Day, -2, GETDATE()) for subtracting 2 days from current date.
I think I understand the logic now:
If the current day is the 1st of the month, get all the records from the start of previous month, until 2 days before it ends.
If the current day is the 2nd of the month, get all the records from the start of the previous month until one day before it ends.
If the current day is the 3rd of the month or higher, get all the records from the beginning of the current month until 2 days ago.
Since you are using the FORMAT() function that was introduced in 2012 version, you can also use the EOMONTH() function that was introduced in the same version.
This function returns the date of the end of the month of the date it receives as an argument, and also have a useful optional second argument that specifies the numbers of months to add to the date passed to the function.
Using this function will allow you to write your query without using any functions on the ServiceDate column, thus enabling the use of any indexes defined on this column.
DECLARE #Now datetime = GETDATE()
SELECT FORMAT(ServiceDate, 'dd-MM-yyy') AS ServiceDate
FROM Services
WHERE (
DAY(#Now) <= 2
AND ServiceDate >= DATEADD(DAY, 1, EOMONTH(#Now, -2))
AND ServiceDate < DATEADD(DAY, -(DAY(#Now)-1), EOMONTH(#Now, -1))
)
OR
(
DAY(GETDATE()) > 2
AND ServiceDate >= DATEADD(DAY, 1, EOMONTH(#Now, -1))
AND ServiceDate < DATEADD(DAY, -2, #Now)
)
Compute enddate as 2 days before getdate() and select data in interval from enddate's first of month and enddate.
SELECT FORMAT(ServiceDate, 'dd-MM-yyy") AS ServiceDate
FROM Services
CROSS APPLY (SELECT enddate = DATEADD(D,-2,getdate()) x
WHERE ServiceDate BETWEEN DATEADD(MONTH,DATEDIFF(MONTH,0,x.enddate),0) AND x.enddate

Select dates inside current month SQL

I have a table similar to one below. I'm trying to select only the rows where the Start Date is in the current month. Here is what I have so far, but it's not working.
SELECT *
FROM TABLE1
WHERE StartDate = MONTH(getdate())
How can I select only the values where the start date is in the current month?
Use this construct to avoid functions on the StartDate columns (like MONTH or YEAR). These functions will prevent any index or statistics being used/
SELECT *
FROM TABLE1
WHERE
StartDate >= DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0)
AND StartDate < DATEADD(month, 1+DATEDIFF(month, 0, GETDATE()), 0)
Any answer that puts a function on StartDate will not scale as expected. See error number 2 here. The filter is now non-sargable, and index/statistics can't be used. Every row will be looked at for a table scan.
You need to check the month of both fields
WHERE MONTH(startdate) = MONTH(getdate())