Need SQL logic
If i enter sys date as 15th it has to fetch the values from 1-15th.
if i enter date as following month 2nd it has to fetch from 15th to
2nd.
Example
Sys date April 15th - April 1 to April 15th date values needs to be fetch.
Sys date May 2nd - April 15th to May 2nd date values needs to be fetch.
Please suggest
So as a general methodology you'd need a function to return the day number in the month, and two case statements to each return a particular date as a boundary. Date arithmetic is used to convert the system date to the upper and lower boundaries required, so on Oracle you'd use Trunc(sysdate,'mm') and add_months(...,n) and add days on as integers.
Date functions are here: http://docs.oracle.com/cd/B28359_01/server.111/b28286/functions001.htm
Can't help you with MySQL functions -- doubtless they're documented somewhere.
you'll end up with ...
date_col > case <function on sysdate>
when < 15 then <function for lower bound case 1>
when < 15 then <function for lower bound case 2>
end and
date_col < case <function on sysdate>
when < 15 then <function for upper bound case 1>
when < 15 then <function for upper bound case 2>
end and
I would recommend using DAYOFWEEK() and MONTH() functions to determine the start and end dates of the query.
SET #day = DAYOFMONTH(<date entered>)
SET #month = MONTH(<date entered>)
IF #month > MONTH(NOW()) AND #day = 2 THEN
SET #start_date = DATE_SUB(<date entered>, INTERVAL 1 MONTH) + INTERVAL 13 DAY
SET #end_date = <date entered>
ELSEIF #month = MONTH(NOW()) AND #day = 15 THEN
SET #start_date = DATE_SUB(<date entered>, INTERVAL 14 DAY)
SET #end_date = <date entered>
END IF;
SELECT * FROM myTable WHERE myDate BETWEEN #start_date AND #end_date
Related
I am trying to indicate all rows with last week's data (Monday-Sunday) using the following, gives me the data from (Tue-Mon) 2 feb-8 feb - so it is dynamic depending on the day of this week and tomorrow will give me the data from Wed-Tue. Any idea how to fix this:
case when `Date` >= date_sub(now(),INTERVAL 1 WEEK) and
`Date`< (date_sub(now(),INTERVAL 1 WEEK)+7) then 1 else 0 end
In mysql you could try using week() checking for the same week of curdate()
case when week(`Date`) = weeek(curdate())
AND year(`Date`) = year(curdate()) then 1 else 0 end
or for the previous week
case when week(`Date`) = weeek(curdate())-1
AND year(`Date`) = year(curdate()) then 1 else 0 end
I'm looking to calculate the start date of the last quarter based on the current date.
Where
Q1 = Jan-Mar
Q2 = Apr-Jun
Q3 = Jul-Sep
Q4 = Oct-Dec
Hence, if the current date is 8th Jan 2018, the function would return the date 1st Oct 2017.
I have written the following code, however, this seems clunky and inelegant, and I have a feeling that there may be a better way to write it (for example, using dateadd).
Function LMLastQuarterStart() As Date
Dim mo As Integer
Dim yr As Integer: yr = Year(Date)
Select Case Month(Date)
Case 1 To 3: mo = 10: yr = yr - 1
Case 4 To 6: mo = 1
Case 7 To 9: mo = 4
Case Else: mo = 7
End Select
LMLastQuarterStart = DateSerial(yr, mo, 1)
End Function
I would appreciate any advice/suggestions offered, thanks.
The function you're looking for, with the DateAdd, is the following:
Public Function LastQuarter(theDate As Date) As Date
LastQuarter = DateAdd("q", DatePart("q", theDate) - 2, DateSerial(Year(theDate), 1, 1))
End Function
Explanation:
DateSerial(Year(theDate), 1, 1)) returns the first quarter of the current year.
DateAdd("q", DatePart("q", theDate), ThatDate) adds the current quarter, returning the next quarter (e.g. quarter 1 -> quarter 2). So the -2 substracts two quarters.
About clunkyness: this function may be shorter and possibly include less operations, but it's harder to understand. That may or may not be relevant.
And about parameters: I have made it take a date, to both make it easy to test and to let you keep it variable. You can do with that what you will.
Thanks to Gustav for making the suggestion to use DatePart instead of Format
I'm using DAYOFWEEK() function in MySQL which returns 1 for sunday. But in my country the week starts with monday, not sunday. Is there any chance to get dayofweek from MySQL formated like: (1 - Monday, 2 - Tuesday, ...) ?
Use WEEKDAY() instead of DAYOFWEEK(), it begins on Monday.
If you need to start at index 1, use or WEEKDAY() + 1.
Try to use the WEEKDAY() function.
Returns the weekday index for date (0 = Monday, 1 = Tuesday, … 6 =
Sunday).
How about subtracting one and changing Sunday
IF(DAYOFWEEK() = 1, 7, DAYOFWEEK() - 1)
Of course you would have to do this for every query.
You can easily use the MODE argument:
MySQL :: MySQL 5.5 Reference Manual :: 12.7 Date and Time Functions
If the mode argument is omitted, the value of the default_week_format system variable is used:
MySQL :: MySQL 5.1 Reference Manual :: 5.1.4 Server System Variables
Could write a udf and take a value to tell it which day of the week should be 1 would look like this (drawing on answer from John to use MOD instead of CASE):
DROP FUNCTION IF EXISTS `reporting`.`udfDayOfWeek`;
DELIMITER |
CREATE FUNCTION `reporting`.`udfDayOfWeek` (
_date DATETIME,
_firstDay TINYINT
) RETURNS tinyint(4)
FUNCTION_BLOCK: BEGIN
DECLARE _dayOfWeek, _offset TINYINT;
SET _offset = 8 - _firstDay;
SET _dayOfWeek = (DAYOFWEEK(_date) + _offset) MOD 7;
IF _dayOfWeek = 0 THEN
SET _dayOfWeek = 7;
END IF;
RETURN _dayOfWeek;
END FUNCTION_BLOCK
To call this function to give you the current day of week value when your week starts on a Tuesday for instance, you'd call:
SELECT udfDayOfWeek(NOW(), 3);
Nice thing about having it as a udf is you could also call it on a result set field like this:
SELECT
udfDayOfWeek(p.SignupDate, 3) AS SignupDayOfWeek,
p.FirstName,
p.LastName
FROM Profile p;
I have a report that runs embedded SQL that uses a simple #startDate and #endDate parameter and the variables in a WHERE clause:
And DM.FromDateTime Between #startDate AND #endDate
What I would like to accomplish is to have an additional parameter that would return only the day of the week the user selected.
For example, if the user chose 3/1/2015 to 3/31/2015 as their date range and selected 'Monday', the report would only populate with data from 3/2, 3/9, 3/16, 3/23, and 3/30.
I know SQL has datepart (dw) function, but any advice on how to handle this parameter?
Create a new integer report parameter #DayOfWeek. It's available values are:
'Sunday' = 1
'Monday' = 2
'Tuesday' = 3
'Wednesday' = 4
'Thursday' = 5
'Friday' = 6
'Saturday' = 7
Then your where clause is simply:
And DM.FromDateTime Between #startDate AND #endDate
AND DATEPART(WEEKDAY, DM.FromDateTime) = #DayOfWeek
My task is to get the records between 2fromdate and todate(given as a input parameters).
i am not able to use between operator for 2 input parameters...
My query as follows...
DELIMITER $$
CREATE DEFINER=`testrunner`#`%` PROCEDURE `usp_GetAllTranasactions`(pFromDate nvarchar(30),pToDate nvarchar(30),pstatus int)
BEGIN
select
ST.UserID,U.Username,
ST.SubscriptionID,
ST.DateOfSubscription,
SM.SubType,
SM.Details,
ST.Amount,
ST.EndDate,
ST.Status
from tr_t_subscriptiontransactions ST
Join tr_m_users U on U.UserID=ST.UserID
join tr_m_subscription SM on SM.SubscriptionID=ST.SubscriptionID
where **ST.DateOfSubscription between (pFromDate and pToDate) and ST.EndDate
between(pFromDate and pToDate) and ST.Status=pstatus;**
END if;
END
here i don't know how to use between parameters..plz help me..i want to retrive record between fromdate and todate..hope u understand..
Let us assume you want all transactions for the month of June 2014
In your user interface the parameter values are:
from_date = 2014-06-01
to_date = 2014-06-30
But you will evaluate against a transaction date & time. How do you ensure that absolutely every transactions on June 30 - right up to midnight - is included in the results?
Here is how: use 2014-07-01 instead of 2014-06-30, and here is what the query would look like - which does NOT use between!
SELECT
ST.UserID
, U.Username
, ST.SubscriptionID
, ST.DateOfSubscription
, SM.SubType
, SM.Details
, ST.Amount
, ST.EndDate
, ST.Status
FROM tr_t_subscriptiontransactions ST
JOIN tr_m_users U
ON U.UserID = ST.UserID
JOIN tr_m_subscription SM
ON SM.SubscriptionID = ST.SubscriptionID
WHERE (ST.DateOfSubscription >= pFromDate AND ST.DateOfSubscription < pToDate + 1)
AND (ST.EndDate >= pFromDate AND ST.EndDate < pToDate + 1)
AND ST.Status = pstatus
;
AVOID between for date ranges because it INCLUDES both the lower and upper boundary values.
... equivalent to the expression (min <= expr AND expr <= max)
http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#operator_between
What this can lead to is an "anti-pattern" which look like this:
where dt_field between '2014-06-01 00:00:00' and '2014-06-30 23:59:59'
but there are time units smaller than one second, so that approach is imperfect. Don't attempt to overcome the deficiencies of between by adjusting the upper value this way. The simple and more accurate approach is to use >= and < adjusting the upper value by one whole time unit (usually the next day).