DATEADD conditon take long time in SQL Server 2008 .Why? - sql

I would like to get data between previous month and current month in my sale table. I use the dateadd function to get month. But the query take long time to return result. When I remove date range in where clause, execution time is very fast. How can I add date range for month to fast execution time in query?
Here is my query.
select *
from sales S
where S.DOCUMENT_DATE >= DATEADD(m, DATEDIFF(m, 0, GETDATE())-1 , 0) and
S.DOCUMENT_DATE <= DATEADD(m, DATEDIFF(m, 0, GETDATE())+1 , -1)

Given your query, you want an index on sales(document_date).

You could create a Nonclustered Index.
CREATE NONCLUSTERED INDEX NC_IX_Sales_DOCUMENT_DATE ON Sales (DOCUMENT_DATE)
Then you could run your query.
SELECT *
FROM Sales s
WHERE s.DOCUMENT_DATE >= DATEADD(mm,DATEDIFF(mm,0,DATEADD(mm,-1,GETDATE())),0)
AND s.DOCUMENT_DATE <= DATEADD(ms,-3,DATEADD(mm,DATEDIFF(m,0,getdate())+1, 0))
Also you could take in account that current month has not ended yet.
SELECT *
FROM Sales s
WHERE s.DOCUMENT_DATE >= DATEADD(month,DATEDIFF(month,0,DATEADD(month,-1,GETDATE())),0)
AND s.DOCUMENT_DATE <= GETDATE()

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();

How to aggregate totals for a given week and each respective weekday?

I'm currently trying to build logic that will independently total each day of the week for the current week given the day the report is run. I need to figure out how to build a query to aggregate each day (and the total weekly sum) as separate columns.
Below I've only provided the subqueries I would use for the Total and Sunday:
DECLARE
#SundayOfCurrentWeek date
, #MondayOfCurrentWeek date
, #TuesdayOfCurrentWeek date
, #WednesdayOfCurrentWeek date
, #ThursdayOfCurrentWeek date
, #FridayOfCurrentWeek date
, #SaturdayOfCurrentWeek date
set #SundayOfCurrentWeek = DATEADD(wk, DATEDIFF(wk,0,getdate()), -1)
set #MondayOfCurrentWeek = DATEADD(wk, DATEDIFF(wk,0,getdate()), 0)
set #TuesdayOfCurrentWeek = DATEADD(wk, DATEDIFF(wk,0,getdate()), 1)
set #WednesdayOfCurrentWeek = DATEADD(wk, DATEDIFF(wk,0,getdate()), 2)
set #ThursdayOfCurrentWeek = DATEADD(wk, DATEDIFF(wk,0,getdate()), 3)
set #FridayOfCurrentWeek = DATEADD(wk, DATEDIFF(wk,0,getdate()), 4)
set #SaturdayOfCurrentWeek = DATEADD(wk, DATEDIFF(wk,0,getdate()), 5)
/** Select Total Records Within The Week**/
( select count(*)
from release
where releasetime >= #SundayOfCurrentWeek
AND releasetime <= #SaturdayOfCurrentWeek ) as TotalCount
/** Select All Records As of Sunday**/
( select count(*) as SundayCount
from release
where releasetime >= #SundayOfCurrentWeek
AND releasetime < #MondayOfCurrentWeek ) as SundayCount
;WITH cte AS (
SELECT
DATENAME(dw,releasetime) as DayOfWeekName
,COUNT(*) OVER () as TotalCount
FROM
#release
WHERE
releasetime >= DATEADD(DAY,- DATEPART(dw,GETDATE()) + 1,CAST(GETDATE() AS DATE))
AND releasetime < DATEADD(DAY,7 - DATEPART(dw,GETDATE()) + 1,CAST(GETDATE() AS DATE))
)
SELECT *
FROM
cte
PIVOT (
COUNT(DayOfWeekName)
FOR DayOfWeekName IN (Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday)
) p
Lots of different ways of doing it. I assumed you wanted the results pivoted meaning in columns with the day of the week rather than in rows. So I am showing you one way to Pivot your results. You can also use the conditional aggregation as in another answer. The trick with Pivot is prepare the table you want first then pivot this can be done with a common table expression [cte]. Then using window functions you can easily get to your COUNT(*) for total count or even a running count as well.
TotalCount
COUNT(*) OVER () --note no partition and no order by statement simply count up the result set.
A running count could look something like this:
COUNT(*) OVER (ORDER BY DATEPART(dw,releasetime))
Definitely recommend getting familiar with window functions!
Edit, changed the Date comparisons in the where statement. It will figure out Sunday of the current week automatically and then Sunday of the next week. The reason for Sunday of the next week is I switched it from <= to < because SQL Server will round anything above 23:59:59.997 to 00:00:00.000 the next day you either have to make your end date midnight of Saturday if releasetime has a time component or you make it 12 AM the next day and say less than.
Try this...
SELECT
DATEPART(DW, [date_col]) AS 'Day_of_Week',
COUNT(*) AS 'Count_per_Day'
FROM [Table]
GROUP BY DATEPART(DW, [date_col])
Note that Day_of_Week = 1 for Sunday, 7 for Saturday.

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())

SQL get Monthly, and weekly data

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

sql get count of month

In SQLExpress, I have a table that contains a datetime-column. It is formatted like this:
19.03.2012 00:00:00
Now, there are a lot of dates in there and I want to build a WPFChart, that shows me, how much dates are in march, in april and so on.
How can I manage this in sql that I get the count of one month?
Use:
select month(dateColumn), count(*)
from table
group by month(dateColumn)
You can extract the month of a date with Month() funciton.
than with a simple group by, you get the count for every month
To get only one month...
SELECT
COUNT(*),
SUM(valueColumn)
FROM
yourTable
WHERE
dateColumn >= '20120101'
AND dateColumn < '20120201'
To get multiple months, but grouped by month (and accounting for year).
SELECT
DATEADD(MONTH, DATEDIFF(MONTH, 0, dateColumn), 0),
COUNT(*),
SUM(valueColumn)
FROM
yourTable
WHERE
dateColumn >= '20110301'
AND dateColumn < '20120301'
GROUP BY
DATEADD(MONTH, DATEDIFF(MONTH, 0, dateColumn), 0)