Why is DATEDIFF parsing these dates as dd/mm/yyyy? - sql

I do:
SELECT DATEDIFF(month, Convert(datetime,'01/10/2018',103),
Convert(datetime,'30/04/2019',103)) AS 'Month1',
DATEDIFF(month, '10/01/2018','04/30/2019') AS 'Months2',
DATEDIFF(month, '10/02/2018','05/01/2019') AS 'Months3'
Please show me why it return 6,6,7?

here date format is day month year
DATEDIFF(month, Convert(datetime,'01/10/2018',103),
Convert(datetime,'30/04/2019',103)) AS 'Month1'
so difference of 10 month(october) and 4(april) month =6
below code date format is month day year
DATEDIFF(month, '10/01/2018','04/30/2019') AS Months2,
so again 10(october) and 4(april) month difference is 6
and the 3rd date format is like 2nd
DATEDIFF(month, '10/02/2018','05/01/2019') AS Months3
so difference between 10(october) 2018 and may(5) 2019 is 7
As a result your query showing output 6,6,7

The first 6 is the difference (in months) between 01/10/2018 (October 1, 2018) and 30/04/2019 (April 4, 2019). The CONVERT call is to force the second date to be parsed using date format 103 (i.e. British/French, i.e. dd/mm/yyyy), which makes me suspect that your SQL implementation is set up to parse them as some other format (e.g. US: mm/dd/yyyy).
The second 6 is the difference (in months) between 10/01/2018 (October 1, 2018) and 04/30/2019 (April 30, 2019).
The 7 is the difference (in months) between 10/02/2018 (October 2, 2018) and 05/01/2019 (May 1, 2019). The fact that these dates could be parsed as Feb 10 and Jan 5, but aren't, confirms that your SQL implementation is parsing dates in mm/dd/yyyy format.
If you are really passing dates as strings, I recommend using an unambiguous format (e.g. "October 1, 2018"), as it will make the code clearer, and less brittle.

Related

Custom month numbers that take last 30 days instead of Number of month (SQL Server)

I am trying to create a lag function to return current month and last month streams for an artist.
Instead of returning streams for Feb vs Jan, I wan the function to use the last 30 days as a period for current month, and the previous 30 days as the previous month.
The query that I am currently using is this:
SELECT
DATEPART(month, date) AS month,
artist,
SUM([Streams]) AS streams,
LAG(SUM([Streams])) OVER (PARTITION BY artist ORDER BY DATEPART(month, date)) AS previous_month_streams
FROM combined_artist
WHERE date > DATEADD(m, -2, DATEADD(DAY, 2 - DATEPART(WEEKDAY, GETDATE()-7), CAST(GETDATE()-7 AS DATE)))
GROUP BY DATEPART(month, date), artist;
While this works, it is not giving me the data I need. This is returning the sum of streams for February vs the Streams for the month of January. February seems very low because we only have one week worth of data in February.
My goal is to get the last 30 days from the max date in the table using a lag function. So if the max date is Feb. 7 2023, I want the current month to include data from Jan. 7 2023 - Feb. 7 2023, and the previous month to include data from Dec. 7 2022 - Jan. 7 2023. I am thinking to create a custom month date part that will start from the max date and give a month number to the last 30 days . (2 for Jan 7 - Feb 7, 1 for Dec 7 - Jan-7...) I am not sure how to go about this. This is in SQL Server and I am looking to use the lag function for performance reasons.
I think you could probably use something like datediff(d, date_you_care_about, max_date)/30 in your group by and partition by clauses.
The basic idea is that integer division rounds down, so if the difference between the dates is < 30, dividing it by 30 is 0. If the difference is >=30 but less than 60, dividing it by 30 is 1. And so forth.
You can see a proof of concept in this Fiddle.

not getting previous month record using datepart in sybase

Using below depart syntax to fetch for previous month record, it is working fine till previous year,however it is giving 0 value in January month.How can we get pervious month with date part even if year is change ?
DATEPART(month(GETDATE()) -1
I understand that I used another type of DB, but I want to give a hint. I am using sql server 2019.
Firstly, you need to substitute date and only then take datepart from it.
Queries:
--dateadd -1 would subtract 1 from current month
--(Jan - 1 2022), would be December 2021
select datepart(month, dateadd(month, -1, getdate()))
--also date add covers internally the problem with 30,31 days.
--May always has 31 days, April 30. So -1 subtraction from 31th of May,would result in 30th of April.
select dateadd(month, -1, cast('2021-05-31 10:00:00' as datetime))

Getting the right date in sql

I'm executing the next query in sql server 2012.
select *
from table
where date > convert(date, '2015/02/12')
order by date asc
but I'm getting the next set:
2015-02-12 06:40:42.000
2015-02-12 06:45:44.000
2015-02-12 06:48:15.000
2015-02-12 07:06:28.000
2015-02-12 07:26:46.000
...
I can fix this by changing the date to '2015/02/13', but I have the doubt about this behavior, why am I getting dates from feb 12 when I am specifying that I need only later dates ?. I also tried using cast('2015/02/12' as date), but I could not have the answer I was looking for
Because dates without times are intepreted as 12:00 midnight on that date. If you want only dates after February 12, 2015, then select all dates greater than or equal to February 13, 2015 (which again will be interpreted as midnight on February 13th).
select *
from table
where date >= convert(date, '2015/02/13')
order by date asc
why am I getting dates from feb 12 when I am specifying that I need only later dates ?
You're not specifying that you need only dates after Feb 12. You're asking for every row in which the value in the "date" column is greater than '2015-02-12'.
The value '2015-02-12 06:40:42.000' is greater than '2015-02-12'.
When comparing the date 2015/02/12 with your datetime data, this will implicitly compare the converted date 2015-02-12 00:00:000, the date at the beginning of the day with all of your data in column date.
But you are actually comparing datetime data, which has a time part as well, which gets compared.
And because you're comparing the beginning of the day (2015-02-12 00:00:000) with a value which is after it, for example 2015-02-12 06:40:42, all of the dates from will be displayed, because 6:40 AM is after (greater than) 0:00 AM.
Try this:
SELECT *
FROM TABLE
WHERE DATE >= DATEADD(SECOND, -1, '2015/02/13')
jarlh is right, though I'll clarify a little. Each of the "dates" you show above fall after 12:00 midnight starting 2015-02-12. They are actually timestamps.
If you don't want to see anything for the day specified in the filter, you add a day and use the greater-than-or-equal-to (>=) operator.
SELECT *
FROM table
WHERE (date >= DATEADD(d, 1, CONVERT(date, '2015/02/12')))
ORDER BY date ASC

What number formats would to_number(to_char(sysdate, 'ydddhh24mi')) produce?

We're transferring a legacy Oracle SQL application to a new platform and I cannot locate proper date format documentation.
What type of numbers would be produced by
SELECT to_number(to_char(sysdate, 'ydddhh24mi')) FROM dual
if sysdate were
January 3, 2015 at 6:04 AM
December 23, 2000 at 4:17 PM
TO_CHAR documentation for Oracle 8 is at http://docs.oracle.com/cd/A87861_01/NT817EE/index.htm; this leads to the format model documentation at http://docs.oracle.com/cd/A87861_01/NT817EE/server.817/a85397/sql_elem.htm#34512. Using the table there...
y returns the last digit of the year.
ddd returns the day of the year.
hh24 returns the military hour of the time.
mi returns the minute of the hour.
For January 3rd, 2015 # 6:04 AM this is 50030604.
For December 23rd, 2000 # 4:17 PM this is 03571617.

Convert date to first of current month if date is previous to current month

I have a query with an IIF() expression in one column that I am using to identify if a date is previous to the current month to then amend it if so. So if I run the query on 19th March 2014 and the EffFrom date is before 1st March 2014, I would want that column entry to now appear as 1st March 2014.
I am using the below expression which is pretty much doing what I want, however I know it is not considering the year -- i.e. it is changing an entry of 1st Jan 2015 to be 1st March 2014.
EffFrom:
IIf(Month([Table.Efffrom])"Less than symbol"Month(Date()),Date()-Day(Date())+1,[Table.Efffrom])
Can someone correct the expression for me?
I interpreted "if I run the query on 19th March 2014 and the efffrom date is before 1st March 2014 I would want that column entry to now appear as 1st March 2014" to mean you want something like this from a query run today (Mar 19th 2014):
id Efffrom adjusted_date
1 1/1/2014 3/1/2014
2 3/1/2014 3/1/2014
3 3/31/2014 3/31/2014
4 1/1/2015 1/1/2015
If that is correct, your IIf expression can use DateSerial to check whether Efffrom is before the first of this month, and transform the older dates.
SELECT
y.id,
y.Efffrom,
IIf
(
y.Efffrom < DateSerial(Year(Date()), Month(Date()), 1),
DateSerial(Year(Date()), Month(Date()), 1),
y.Efffrom
) AS adjusted_date
FROM YourTable AS y;
Here's what i do to get the first day of the next month
EffFrom: DateAdd("m",1,CDate(Format([Table.Efffrom],"m/\1/yy")))