I want to create an SQL statement that looks for the last 2 months.
For example:
Select *
from x
where sampledate<= YYYYMM-2
currently i am using this:
(year(from_unixtime(unix_timestamp()))*100+month(from_unixtime(unix_timestamp())))-1
but it returns wrong statements for the first 2 months of a year :(
My idea is to calculate with a date and then change it to a yyyymm integer format.
Any ideas?
Could you try this:
SELECT colomn
FROM table
WHERE date > (SELECT add_months(from_unixtime(unix_timestamp()),-2));
or you can use:
SELECT colomn
FROM table
WHERE date > to_date(SELECT year(add_months(from_unixtime(unix_timestamp()),-2))+month(add_months(from_unixtime(unix_timestamp()),-2)));
Combined with regex&substring:
SELECT colomn
FROM table
where sampledate>=substr(regexp_replace(add_months(from_unixtime(unix_timestamp()),-2), '-',''),1,6)
to get a YYYYMM date
If you want to avoid converting an integer, in YYYYMM format, to and from a date, you can just use maths and CASE statements...
For example YYYYMM % 100 will give you MM. Then you can check if it's 2 or less. If it is 2 or less, deduct 100 to reduce by a year, and add 12 to get the month as 13 or 14. Then, deducting 2 will give you the right answer.
Re-arranging that, you get YYYYMM - 2 + (88, if the month is 1 or 2)
sampledate <= YYYYMM - 2 + CASE WHEN YYYYMM % 100 <= 2 THEN 88 ELSE 0 END
The better idea may just be to reshape your data so that you actually have a (real) date field, and just use ADD_MONTHS(aRealDate, -2)...
EDIT:
If your actual issue is generating the YYYYMM value for "two months ago", then deduct the 2 months before you use the YEAR() and MONTH() functions.
year( ADD_MONTHS(from_unixtime(unix_timestamp()), -2) )*100
+
month( ADD_MONTHS(from_unixtime(unix_timestamp()), -2) )
Try something like this.
First, a utility to get the date n months in the future/past:
public Date nMonthsFromDate(Date date, int interval) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
// E.G. to get 2 months ago, add -2
cal.add(Calendar.MONTH, interval);
Date result = cal.getTime();
return result;
}
Criteria query on the entity, here Member:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Member> q = cb.createQuery(Member.class);
Root<Member> memberRoot = q.from(Member.class);
Date theDate = nMonthsFromToday(-2);
Predicate pred = cb.greaterThanOrEqualTo(
memberRoot.<Date>get("timeStamp"), theDate);
q.where(pred);
TypedQuery<Member> theQuery = em.createQuery(q);
String qStr = theQuery
.unwrap(org.apache.openjpa.persistence.QueryImpl.class)
.getQueryString();
LOG.info("Query: " + qStr);
List<Member> results = null;
try {
results = theQuery.getResultList();
} catch (Exception e) {
LOG.severe(e.getMessage());
e.printStackTrace();
}
return results;
Finally, beware of comparing a date [java.util.Date] to a timestamp [util.sql.Date]. Due to a quirk in Java, for equivalent dates, date.equals(timeStamp) returns true, BUT timeStamp.equals(date) returns FALSE. To conform both dates to a java.util.Date:
public java.util.Date getStandardDate(Date date) {
return new java.util.Date(date.getTime());
Related
I have file with a column dates.
I want to get the dates which precede the current date with interval of two years.
I mean; we are 18/08/2021: I want all dates before 18/08/2019. of course with a dynamic date.
so tomorrow i will get all the dates before 19/08/2019
You can achieve this with a DAX measure as following
Include/Exclude:=
VAR _1 =
DIVIDE(CONVERT ( TODAY () - MAX ( tbl[Dates] ), INTEGER )-1, 365)
VAR _2 =
SWITCH ( TRUE (), _1 > 2, "Include", "Exclude" )
RETURN
_2
Do you simply want a where clause?
where datecol < dateadd(year, -2, convert(date, getdate()))
I am facing some problem with the hive code.
My FROM TABLE is partitioned based on month, year and day. I came up with the following code to get the data I need. The logic is something like if the current mth is 01 then change the month to 12 and the year to yr - 1
else change month to mth - 1 and keep the year as is.
set hivevar:yr=2019;
set hivevar:mth=03;
set hivevar:dy=29;
SELECT * from
FROM table
WHERE
month = case when cast('${mth}' as int) = 01 then 12 else cast((cast('${mth}' as int) - 1) as string) end
AND year = case when cast('${mth}' as int) = 01 then cast((cast('${yr}' as int) - 1) as string) else '${yr}' end;
It is not working, my select * is coming empty. Please help.
desc table
From what i understand, you are trying to get data from the previous month given a date. If so, you can use inbuilt date functions to do it.
select *
from table
where concat_ws('-',year,month,day) >= add_months(date_add(concat_ws('-','${yr}','${mth}','${dy}'),1-'${dy}'), -1)
and concat_ws('-',year,month,day) < date_add(concat_ws('-','${yr}','${mth}','${dy}'),1-'${dy}')
The solution assumes year, month and day are of the format yyyy, MM and dd. If not, adjust them as needed
Also, you should consider storing date as a column even though you have it partitioned by year,month and day.
I have a date field in a hive table following this format:
'YYYY-MM-DD'
I'm looking for a function (let's call this yet-to-be-discovered-by-me function dayofweek()) that will return 'friday' when run on today's date. So, to be explicitly clear, this query:
SELECT DAYOFWEEK(DT.ds), DT.ds
FROM dateTable DT
WHERE DT.ds = '2014-11-14'
LIMIT 1
would return this value:
'friday' '2014-11-14'
Any help would be greatly appreciated :) google searching as of yet unfruitful.
Clark
P.S. The response to this question did not work for me...error returned: 'Invalid function 'dayofweek''
Should you care for an equation, following is C code hopefully simple enough to translate into SQL.
Important to use integer math.
#define MARCH 3
int dow_Sunday0(int year, int month, int day) {
if (month < MARCH) {
month += 12;
year--;
}
// Add days for each year and leap years
day += year + year/4 - year/100 + year/400;
// add days for the month
day += month*30 + ((month-MARCH)*39 + 25)/64;
// modulo 7
return (day+3)%7;
}
This works for valid Gregorian calendar dates.
Use DAYNAME() function, like this:
mysql> select dayname('2014-11-14');
+-----------------------+
| dayname('2014-11-14') |
+-----------------------+
| Friday |
+-----------------------+
1 row in set (0.00 sec)
So, your query will become:
SELECT DAYNAME(DT.ds), DT.ds
FROM dateTable DT
WHERE DT.ds = '2014-11-14'
LIMIT 1
I have salesdate for whole last year (01/01/2012 to 12/31/2012). I want to create
a week variable in such a way that there are only 4 weeks consistent over the months.
In other words, I want
01/01/2012-01/07/2012 = week1
01/08/2012-01/14/2012 = week2
01/15/2012-01/21/2012 = week3
01/22/2012-01/31/2012 = week4
(I can not use ww. format because my week 4 does not fit the always definition of week 4 in Oracle SQL Developer.)
I am wondering if anybody can help me on this.
Try this expression:
select LEAST(TRUNC((EXTRACT(day FROM salesdate) + 6) / 7), 4) week
FROM salesdata;
Note:
EXTRACT extracts the day from the date
TRUNC( (x + 6) / 7) divides it by seven days and truncates it to an integer number
LEAST( x, 4 ) limits it to a maximum of 4
Well your last week has 9 days, so that is kind of weird...
but you could try something like:
CREATE OR REPLACE FUNCTION GET_WEIRD_WEEK(I_DATE DATE)
RETURN NUMBER AS
BEGIN
RETURN CASE
WHEN FLOOR(TO_CHAR(I_DATE,'DD')/7)+1 > 3
THEN 4
ELSE FLOOR(TO_CHAR(I_DATE,'DD')/7)+1
END;
END;
otherwise i would suggest you distribute the days evenly across the month's quarters:
CREATE OR REPLACE FUNCTION GET_WEIRD_WEEK(I_DATE DATE) RETURN NUMBER AS
BEGIN
RETURN FLOOR(TO_CHAR(I_DATE,'DD')/TO_CHAR(LAST_DAY(I_DATE),'DD')*4)+1;
END;
I have a table with records from many dates.
I would like to perform a query that only returns records that fall on the last day of the date's month. Something like:
SELECT * FROM mytable
WHERE DATEPART(d, mytable.rdate) = DATEPART(d,DATEADD(m,1,DATEADD(d, -1, mytable.rdate)))
Except this doesn't work as the rdate in the right-hand side of the argument should be the last day of it's month for the dateadd to return the correct comparison.
Basically is there an concise way to do this comparison?
An equivalent for quarter-ends would also be very helpful, but no doubt more complex.
EDIT:
Essentially I want to check if a given date is the last in whatever month (or quarter) it falls into. If it is, return that record. This would involve a some function to return the last day of the month of any date. e.g. lastdayofmonth('2013-06-10') = 30 (so this record would not be returned.
EDIT2:
For the case of returning the records that fall on the last day of the quarter they are in it would need to be something like:
SELECT * FROM mytable
WHERE DATEPART('d', mytable.rdate) = lastdayofmonth(mytable.rdate)
AND DATEPART('m', mytable.rdate) = lastmonthofquarter(mytable.rdate);
The tricky bit is the lastdayofmonth() and lastmonthofquarter() functions
Use the DateSerial Function to compute the last day of the month for a given date.
Passing zero as the third argument, day, actually returns the last date of the previous month.
rdate = #2013-7-24#
? DateSerial(Year(rdate), Month(rdate), 0)
6/30/2013
So to get the last date from the rdate month, add 1 to the month argument.
? DateSerial(Year(rdate), Month(rdate) + 1, 0)
7/31/2013
You might suspect that approach would break for a December rdate, since Month() + 1 would return 13. However, DateSerial still copes with it.
rdate = #2013-12-1#
? DateSerial(Year(rdate), Month(rdate) + 1, 0)
12/31/2013
If you will be running your query from within an Access application session, you can build a VBA function based on that approach, and use the custom function in the query.
However, if the query will be run from an ODBC or OleDb connection to the Access db, the query can not use a VBA user-defined function. In that situation, you can use DateSerial directly in your query.
SELECT m.*
FROM mytable AS m
WHERE m.rdate = DateSerial(Year(m.rdate), Month(m.rdate) + 1, 0)
That should work if your rdate values all include midnight as the time component. If those values include other times, use DateValue.
WHERE DateValue(m.rdate) = DateSerial(Year(m.rdate), Month(m.rdate) + 1, 0)
Try This.
SELECT * FROM mytable
WHERE DATEPART(d, mytable.rdate) =
DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, GETDATE()) + 1, 0))
Try this one, this is tested on MS Access:
Using String Concatenation:
SELECT * FROM mytable
WHERE
DatePart('d',mytable.rdate) =
DatePart('d',dateadd('m',1, "1/" & DatePart('m',mytable.rdate) & "/" & DatePart('yyyy',mytable.rdate))-1);
Update without using string concatenation:
SELECT * FROM
(SELECT *,
DATEPART('d',DATEDIFF('m',0,mytable.rdate)+1,
DATEADD('m',1,
DATEADD('d',DATEDIFF('d',0,mytable.rdate)- DATEPART('d',mytable.rdate)+1,0))-1) as EOMonth
FROM mytable ) A
WHERE DATEPART('d',mytable.rdate) = DATEPART('d',EOMonth)