MS SQL query between (today) and 30 days ago - sql-server-2008

Microsoft SQL 2008 (using Visual Studio 2010 to build and test query).
Query function: This query is going to be run via batch file in Windows Task Scheduler. The goal is to be able to create a CSV file every month.
My query:
SELECT TYPE, DATEX, TIME, STREET, CROSS_ST, XCOORD, YCOORD
FROM INCIDENT
WHERE (TYPE = '644') OR
(TYPE = '459') OR
(TYPE = 'HS') OR
(TYPE = '484') OR
(TYPE = '487') OR
(TYPE = '488') OR
(TYPE = '10851') OR
(TYPE = '187') OR
(TYPE = '211') OR
(TYPE = '245') OR
(TYPE = '451')
ORDER BY DATEX
I am trying to sort the 'DATEX' column (which is in datetime format) between 'today's date' and '30 days ago'
I have tried all of these statements and none of them work:
(DATEX < DATEADD(month, - 1, GETDATE()))
DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL 1 MONTH)),
(
CONVERT(varchar, DATEX, 110) AS DATE,
DATEX CONVERT(varchar, DATEADD(d,-30,GETDATE()), 23)
)
*ERROR INTERVAL is not recognized
AND DATEX BETWEEN DATEADD(mm,-1,GETDATE()) AND DATEADD(mm,1,GETDATE())
*error unrecognized syntax 1
=DateAdd("d", -7, Today()) *Today is not a recognized function
where date_col > DATEADD(day,-7,SYSDATETIME())
*unrecognized syntax near 'Where'
where DATEDIFF(day,date_col,SYSDATETIME()) < 7
*error near 'WHERE'
DATEX Dte < DATEADD(month, -2, GETDATE())
*an expression of non-Boolean type specified
AND (DATEX BETWEEN ({ fn CURDATE() }, 30) AND { fn CURDATE() })
*incorrect syntax near ','
What is the correct syntax for Microsoft SQL query to sort a table 'incident' between 'today's date' and '30 days ago'?
Please note that simply using Between 'YYYY-MM-DD' and 'YYYY-MM-DD' is not helpful because I would need to manually change the dates to run the query. I want to automate it to create a CSV file every month.

Instead of throwing everything at the wall and seeing what sticks, I strongly recommend reading the vendor's documentation. Microsoft SQL Server has extremely comprehensive and readable documentation, even among RDBMSs, both on the web and if you install the fantastic SQL Server Books Online.
As to your issue, you'll need to use DATEADD(). The problem, however, is that datetime fields and GETDATE() have a time component, and you need to account for that.
So, one of the keys you'll need to know, is how to strip the time from a datetime. If you're on SQL Server 2008 R2 and higher, you can do this:
CAST(GETDATE() AS DATE)
But that doesn't work on SQL Server 2008 and earlier. Instead, you need to use this:
DATEADD(dd, DATEDIFF(dd, 0, GETDATE()), 0)
If you know that DATEX is never in the future, you can use this:
SELECT TYPE, DATEX, TIME, STREET, CROSS_ST, XCOORD, YCOORD
FROM INCIDENT
WHERE TYPE IN ('644','459','HS','484','487','488','10851','187','211','245','451')
AND DATEX >= DATEADD(dd, DATEDIFF(dd, 0, GETDATE()) - 30, 0)
ORDER BY DATEX
Which is, "DATEX is on or after midnight 30 days ago."
Now, if DATEX might be in the future, but it always has a zero time value, you can use this:
SELECT TYPE, DATEX, TIME, STREET, CROSS_ST, XCOORD, YCOORD
FROM INCIDENT
WHERE TYPE IN ('644','459','HS','484','487','488','10851','187','211','245','451')
AND DATEX BETWEEN DATEADD(dd, DATEDIFF(dd, 0, GETDATE()) - 30, 0) AND GETDATE()
ORDER BY DATEX
Which is, "DATEX is on or after midnight 30 days ago and on or before right now." On the other hand, if DATEX might be in the future and will have a non-zero time component, you should use this:
SELECT TYPE, DATEX, TIME, STREET, CROSS_ST, XCOORD, YCOORD
FROM INCIDENT
WHERE TYPE IN ('644','459','HS','484','487','488','10851','187','211','245','451')
AND DATEX >= DATEADD(dd, DATEDIFF(dd, 0, GETDATE()) - 30, 0)
AND DATEX < DATEADD(dd, DATEDIFF(dd, 0, GETDATE()) + 1, 0)
ORDER BY DATEX
This is "DATEX is on or after midnight 30 days ago and before midnight tomorrow." It's easier to refer to "before midnight tomorrow" because datetime can have fractional seconds.

You can use Dateadd Function also remove the multiple OR conditions and use IN clause
SELECT TYPE, DATEX, TIME, STREET, CROSS_ST, XCOORD, YCOORD
FROM INCIDENT
WHERE DATEX BETWEEN DATEADD(dd,-30,GETDATE()) AND GETDATE()
AND TYPE in ('644','459','HS','484','487','488','10851','187','211','245','451')
ORDER BY DATEX

This should work for your condition.
WHERE DATEX BETWEEN GETDATE()-30 AND GETDATE()
it will minus 30 days off from todays date

Your query should be something like this
SELECT TYPE, DATEX, TIME, STREET, CROSS_ST, XCOORD, YCOORD
FROM INCIDENT
WHERE DATEX > DATEADD(dd, -30, CAST(CAST(GETDATE() AS INT) AS DATETIME)) AND
((TYPE = '644') OR
(TYPE = '459') OR
(TYPE = 'HS') OR
(TYPE = '484') OR
(TYPE = '487') OR
(TYPE = '488') OR
(TYPE = '10851') OR
(TYPE = '187') OR
(TYPE = '211') OR
(TYPE = '245') OR
(TYPE = '451'))
ORDER BY DATEX
Here you can find a working demo
Hope this helps

Related

Set Date Format in Variable

Just wondering if anyone can help me setting a date variable for a report to run between certain dates every year without needing to be updated manually.
For example, I have the dates hard-coded below, but I was wondering if I could set a date format for when it goes into 2017 that the dates will change for the 2017 year. I presume there is a way to set a yearly date format I am just not sure how.
This is my hard-coded variables I set.
Put in the wrong Date Ranges changed as below.
set #start_date = '2016-01-02';
set #end_date = '2017-01-01';
Below is what I have in my where clause also.
and create_date between #start_date and #end_date
Your range covers all days in the year, except January 1. So you can simply check the day and month:
WHERE NOT (DAY(create_date) = 1 AND MONTH(create_date) = 1)
set #start_date = CAST(CAST(YEAR(getdate()) AS nvarchar(4)) + '0102' AS DATETIME);
to get end of current year
SET #end_date = DATEADD(day, -1 , DATEADD(month,13 - MONTH(getdate()), DATEADD(day,1 - DAY(getdate()),getdate())));
I assume you want the FULL "current year" based on "today"
MySQL
select *
from whatever
where ( create_date >= CONCAT(YEAR(CURDATE()),'-01-01')
and create_date < CONCAT(YEAR(CURDATE())+1,'-01-01')
)
Test it with:
SELECT
CONCAT(YEAR(CURDATE()),'-01-01') This_year_start
, CONCAT(YEAR(CURDATE())+1,'-01-01') Next_year_start
SQL Server (tsql)
select *
from whatever
where ( create_date >= DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0)
and create_date < DATEADD(YEAR, DATEDIFF(YEAR, -1, GETDATE()), 0)
)
Test it with:
select
DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()) , 0) This_year_start
, DATEADD(YEAR, DATEDIFF(YEAR, -1, GETDATE()), 0) Next_year_start
This_year_start Next_year_start
01.01.2016 00:00:00 01.01.2017 00:00:00
DATEDIFF(YEAR, 0, GETDATE()) calculates the number of years from the
base year
add that number of years to the base date (1900-01-01)
DATEDIFF(YEAR, -1, GETDATE()) calculates the number of years from
year before the base year (is a bigger number, by 1, than above)
add that number of years to the base date (1900-01-01)
Please avoid using between for date ranges. It is far safer to use a combination of >= and <
e.g.
where create_date >= '2016-01-01' and create_date < '2017-01-01'
With that approach, no matter what time precsion applies to the data in [create_date] you will get the precise range of information requested.
Here you go.
declare #s datetime, #e datetime
set #s=cast(cast(year(getdate()) as char(4))+'-01-02' as date)
set #e=cast(cast(year(getdate()) as char(4))+'-12-31' as date)
select #s,#e

How to convert MSSQL to MySQL date in PHP

I am a PHP developer and I am working in converting MSSQL to MySQL file while converting data's
CAST(0x063A0B00 AS Date)
I cant convert this as a timestamp.
SELECT
CAST(
'1900-01-01 00:00:00' +
INTERVAL CAST(CONV(substr(HEX(BinaryData),1,8), 16, 10) AS SIGNED) DAY +
INTERVAL CAST(CONV(substr(HEX(BinaryData),9,8), 16, 10) AS SIGNED)* 10000/3 MICROSECOND
AS DATETIME) AS converted_datetime
FROM
(
SELECT 0x0000987C00000000 AS BinaryData
UNION ALL
SELECT 0x00009E85013711EE AS BinaryData
) d
From how to cast the hexadecimal to varchar(datetime)?

data between two specific times in mysql get error

I am trying to select all data from my table where condition is
performDate will be between today 2.00 AM to tomorrow 2.00 AM
My query gives this error
Incorrect parameter count in the call to native function 'DATEDIFF'
My query is
SELECT * FROM `admin_marker` WHERE
FROM_UNIXTIME(performDate)
BETWEEN DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0) + '02:00'
AND DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()+1), 0) + '02:00'
DATEDIFF expects only 2 parameters. You call it with 3 parameter.
Why dont you do it that way ?
WHERE performdate >= DATE_FORMAT(NOW(), '%Y-%m-%d 02:00:00') AND performdate <= DATE_FORMAT(CURRENTDATE + INTERVAL +1 DAY '%Y-%m-%d 02:00:00')

select first day of previous month from record in sql server

I have a table that has a column called StartDateTime that stores datetime values. I need a statement that will return the date of the first day in the previous month of the current record. So, if the stored date is 2006-06-17 08:23:42.000 the statement would return 2006-05-01 00:00:00.000 and importantly if the stored date is 2006-01-17 08:23:42.000 the statement would return 2005-11-1 00:00:00.000
If I could use DATEBYPARTS this seems like it would be simple, but unfortunately I can not.
I tried using
CAST(
CAST( Year([StartDateTime]) as varchar(4) )
+ '-' +
CAST( (Month([StartDateTime])-1) as varchar(2) )
+ '-' +
CAST( '1' as varchar(2) )
AS DATETIME )
but it errors on January 1st dates and gives error "The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value."
select dateadd(mm, datediff(mm, 0, StartDateTime) - 1, 0)
from <yourtable>
Or, as Aaron Bertrand suggested in comments, more clear way
select dateadd(month, datediff(month, 0, StartDateTime) - 1, 0)
from <yourtable>
SQL FIDDLE EXAMPLE

Get previous month range using SYSDATE()

I am trying to use sysdate() to pull data for the previous month.
DECLARE #firstOfLastMonth DATE;
SET #firstOfLastMonth = DATEADD(MONTH, DATEDIFF(MONTH, 0, SYSDATETIME())-1, 0);
SELECT ... FROM ...
WHERE dateColumn >= #firstOfLastMonth
AND dateColumn < DATEADD(MONTH, 1, #firstOfLastMonth);
Here's why you don't want to use BETWEEN for this:
What do BETWEEN and the devil have in common?
Bad habits to kick : mis-handling date / range queries
You mean the current server time minus one month? Try the DATEADD function:
dateadd(month, -1, sysdatetime())
If you want to select records with a column's value being in the past month, you could do:
SELECT foo
FROM bar
WHERE baz BETWEEN dateadd(month, -1, sysdatetime()) AND sysdatetime()