I am trying to do something like this:
IF today is "current MM-DD" then all MM-DD between Sept-01 and "Current MM-DD" are Y else N. In all years.
I have many years in my data (i.e 2017-2024)
IF(date = current_date, "I am lost here")
So my expected answer is: If today is Nov-10 then all years (2017-2024) from Sept-1 to Nov-10 is "Y" and the rest is "N"
You might consider below query.
WITH sample_data AS (
SELECT date FROM UNNEST(GENERATE_DATE_ARRAY('2017-01-01', '2024-12-31')) date
)
SELECT current_date,
date,
IF (FORMAT_DATE('%m-%d', date) BETWEEN '09-01' AND FORMAT_DATE('%m-%d', current_date), 'Y', 'N') in_range
FROM sample_data;
Related
I'm trying to select whether or not the date value in one of my columns takes place before a certain amount of years.
The code I'm trying out:
SELECT CASE
WHEN CAST(my_date AS DATE) + INTERVAL '10' YEAR < CURRENT_DATE THEN 'OVER 10 YEARS AGO'
ELSE NULL AS date_check
My expected output should be NULL for the dates I'm using (e.g. 2019-09-30) as they fall within the last 10 years, but for some reason, I'm getting OVER 10 YEARS AGO for everything.
When I test with values actually over 10 years ago (e.g. 2010-07-17), I'm also getting OVER 10 YEARS AGO as expected, however.
How is it possible to achieve what I'm trying to do? What appears to be wrong with my code?
WITH cte (my_date) AS (
SELECT current_date - INTERVAL '11' YEAR UNION
SELECT '2010-07-17' UNION
SELECT '2019-09-30'
)
SELECT CASE
WHEN CAST(my_date AS DATE) + INTERVAL '10' YEAR < CURRENT_DATE
THEN 'OVER 10 YEARS AGO'
ELSE NULL
END AS date_check
FROM cte
;
Having said that, it's best to perform your calculation against the literal, not your column:
WITH cte (my_date) AS (
SELECT current_date - INTERVAL '11' YEAR UNION
SELECT '2010-07-17' UNION
SELECT '2019-09-30'
)
SELECT CASE
WHEN CAST(my_date AS DATE) < CURRENT_DATE - INTERVAL '10' YEAR
THEN 'OVER 10 YEARS AGO'
ELSE NULL
END AS date_check
FROM cte
;
and, if possible, use the correct type without CAST.
Full test case
New to the forum. I am looking to use a CASE WHEN function based on two separate fields . Those fields are order day and Month . Month is a calculation from:
DATEPART (Month, order_day ) AS Month
The code I have is below, but not getting the desired result. Want to say when order day is between x dates, then have the data in the Month column 1, otherwise give me the normal data that appears in the Month column.
when order_day between to_date ('20201227', 'YYYYMMDD') and TO_DATE ('20201231', 'YYYYMMDD') THEN Month = '1'
else Month End As Month2
Not easy to understand the question, but your case when in a SELECT statement should look like this:
SELECT
case when order_day between to_date ('20201227', 'YYYYMMDD') and TO_DATE('20201231', 'YYYYMMDD')
then Month = '1'
else Month
end
Currently, I am using this code to look at the previous month's data for quicksight in Amazon's Athena (this first part works*):
SELECT month, count(1)
FROM table1
WHERE CAST(EXTRACT(month from now()) - 1 as VARCHAR(2)) = month
GROUP BY month
The challenge is how to ensure that this code will work once we roll over into a new year? I currently have
SELECT month, count(1)
FROM table1
WHERE CASE WHEN( month = '1' THEN month = '13'
ELSE month
END)
CAST(EXTRACT(month from now()) - 1 as VARCHAR(2)) = month
GROUP BY month
To clarify, month was input as a string, hence the CAST as VARCHAR(2) to get "01" through "12".
My thought process behind this was that if month = '01', then it reads it as '13', then extracts '1', equaling '12'. But not sure if that will work
You can use the date_add function to subtract one month from today:
SELECT DATE_ADD('month', -1, NOW())
Alternatively you can subtract an interval of one month to achieve the same results:
SELECT NOW() - INTERVAL '1' MONTH
In both cases you can then use MONTH(…) or EXTRACT(MONTH FROM …) to get the month number.
You seem to want:
where month = extract(month from now()) - 1 or
(extract(month from now()) = 1 and month = 12)
I have two date columns, which takes into account only working days. A_date and E_date.
E_date is calculated adding +2 days to A_date, because that's the request
The problem is that if the day of A_date is 30th or 31st of the month, then E_date date needs to be the last day of the current month, and not the first or second working day of the next month.
i have tried eomonth function but that does not work because it would need a explicit date.
Do you have any idea how to solve it?
You can use EOMONTH() in SQLServer to get the last day of the month.
Example:
EOMONTH(A_date)
SELECT CASE WHEN dateadd(month,1+datediff(month,0,A_date),-1)< DATEADD(day, 2, A_date) THEN dateadd(month,1+datediff(month,0,A_date),-1) ELSE DATEADD(day, 2, A_date) END E_date
FOR input of 2019/09/30 output is 2019-09-30 00:00:00.000
I'm not sure what your question is. What I've understood so far is that you want the last date of the month in case when adding two days to A_Date jumps to the next month.
Why don't you use CASE WHEN and compare out the months, this way :
DECLARE #A_Date date = '2019/09/30';
DECLARE #A_Date_Month int = 0;
DECLARE #E_Date_Month int = 0;
SELECT #A_Date_Month = Month(Cast(#A_Date AS datetime));
SELECT #E_Date_Month = Month(DATEADD(day, 2, #A_Date));
SELECT CASE
WHEN #A_Date_Month = #E_Date_Month
THEN DATEADD(day, 2, #A_Date)
ELSE EOMONTH(#A_Date) END AS OUTPUTValue
Try out the above set and do let me know if it resolves your issue!
How to get from a date column the last date of the previous month?
It depends on your RDBMS, so let's take the opportunity to make a generic answer:
In Oracle:
LAST_DAY(ADD_MONTHS(mydate ,-1))
In MySQL:
LAST_DAY(mydate - INTERVAL 1 MONTH)
In SQL Server:
DATEADD(MONTH, DATEDIFF(MONTH, -1, mydate )-1, -1)
-- or simply:
EOMONTH(DATEADD(Month, -1, mydate ))
In Postgres:
date_trunc('month', now())::mydate - 1
have two date columns, which takes into account only working days. A_date and E_date. E_date is calculated adding +2 days to A_date, because that's the request
I would simply do:
(case when dateadd(day, 2, a_date) < eomonth(a_date)
then dateadd(day, 2, a_date)
else eomonth(a_date)
end) as e_date
If you truly want this only on the 30th or 31st of any given month and not the last 2 days of any month (since obviously not every month has 31 days) --
select A_date
,case when day(A_date) >= 30
then eomonth(A_date)
else dateadd("dd",2,A_date)
end as E_date
Other answers work for "last 2 days of any month".
I want to calculate current age of person from DOB(date of birth) field in Oracle table.
Data type of DOB field is varchar and the is date stored in format 'DD-MON-YY'.
when I calculate current age of a person from date like 10-JAN-49 the query will return age in negative. Also, I observed that if date has year 13 to 49 it gives negative result.
Examples
22-NOV-83 -valid result
09-FEB-58 --valid result
05-JUN-49 - Invalid result like -36
Query Executed for reference
select round(MONTHS_BETWEEN(sysdate,to_date(dob,'DD-MON-RR'))/12)||' Yrs'
from birth
Any help is appreciated!
To get round the 21st century problem, just modifying #the_silk's answer slightly:
SELECT
CASE WHEN SUBSTR(dob, -2, 2) > 13
THEN FLOOR
(
MONTHS_BETWEEN
(
SYSDATE
, TO_DATE(SUBSTR(dob, 1, 7) || '19' || SUBSTR(dob, -2, 2), 'DD-MON-YYYY')
) / 12
)
ELSE
FLOOR(MONTHS_BETWEEN(sysdate,TO_DATE(dob,'DD-MON-YY'))/12)
END
FROM
birth
Please be aware though that this assumes that any date year between '00' and '13' is 21st century, so this sql should only be used if you are building a one off throwaway script, otherwise it will become out of date and invalid before long.
The best solution would be to rebuild this table, converting the varchar column into a date column, as alluded to by Ben.
/*
A value between 0-49 will return a 20xx year.
A value between 50-99 will return a 19xx year.
*/
Source: http://www.techonthenet.com/oracle/functions/to_date.php
SELECT FLOOR
(
MONTHS_BETWEEN
(
SYSDATE
, TO_DATE(SUBSTR(d_date, 1, 7) || '19' || SUBSTR(d_date, -2, 2), 'DD-MON-YYYY')
) / 12
)
FROM
(
SELECT '10-JAN-49' d_date FROM DUAL
)
-- The result: 64
SELECT MONTHS_BETWEEN( to_date(sysdate,'dd-mm-rr')
, to_date(to_date(dob,'yymmdd'),'dd-mm-rr')
) / 12 AS Years
FROM birth;
Maybe this works.
My solution would be something like this:
SELECT DATE_FORMAT(CURDATE(),'%Y') - DATE_FORMAT(dob,'%Y') as age
FROM `member_master`
having age >=30 and age <=35
SELECT year,
months,
Floor(SYSDATE - day_1) AS days
FROM (SELECT year,
months,
Add_months(To_date('30-Oct-1980', 'dd-Mon-yyyy'),
12 * year + months)
day_1
FROM (SELECT year,
Floor(Trunc(Months_between(Trunc(SYSDATE),
To_date('30-Oct-1980', 'dd-Mon-yyyy')
))
- year * 12) AS months
FROM (SELECT Floor(Trunc(Months_between(Trunc(SYSDATE),
To_date('30-Oct-1980',
'dd-Mon-yyyy'
)
)) /
12) AS year
FROM dual)));
Try using YY in the Year part of your TO_DATE
RR Like YY, but the two digits are ``rounded'' to a year in the range 1950 to 2049. Thus, 06 is considered 2006 instead of 1906