How to use between operator for 2 date input parameters in mysql? - mysql

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).

Related

SQL query fetch the complete list of data from table, rather between the date range

I have a question here, the attached screen shot
SELECT
intvw.Tran_no RequestNo, stkdl.std_tran_no RamcoTranNo,
stkhd.sth_tran_date TranDate,
intvw.Bg_Code ItemCode, intvw.reqdqty ReqQty,
stkdl.std_tran_quantity TransferQty,
stkdl.std_from_lot_no, (intvw.reqdqty-stkdl.std_tran_quantity) * -1 Varience,
intvw.From_Wh_Code FromWH, intvw.To_Wh_Code ToWH
FROM
res_his_interface_stock_vw intvw
LEFT JOIN
skm_stocktransfer_dtl stkdl ON intvw.Tran_no = stkdl.std_tran_no
AND intvw.Bg_Code = stkdl.std_item_code
AND intvw.From_Wh_Code = stkdl.std_from_wh_code
LEFT JOIN
skm_stocktransfer_hdr stkhd ON stkhd.sth_tran_no = stkdl.std_tran_no
AND stkhd.sth_tran_date BETWEEN '2020-01-19 00:00:00.000' AND '2020-01-19 00:00:00.000' -- datatype: datetime
AND stkhd.sth_status = 'AU' -- checks transaction authorised or not
WHERE
intvw.From_Wh_Code = 'MAINSTRS'
--AND stkhd.sth_tran_date BETWEEN '2020-01-19 00:00:00.000' AND '2020-01-19 00:00:00.000' -- removes the null rows.
AND intvw.Tran_no = 'R0000085590' -- if commented all rows instead of date range.
ORDER BY
1 DESC
When I keep the date range and tran_no, the below results appear, the moment comments on tran_no and try to see the result for the given date range, instead of it, it gives all data from day one till date.
I don't get know what's wrong here, please help.

Convert time "28:45" to "4:45" MySQL

I'm looking for a way to order my results based on the actual time. In my table yo can see values like:
1,23:45
2,9:45
3,27:43
When I do a query I would like to know how to order them based on their actual 24 hour time.
Ex:
3,3:43
2,9:45
1,23:45
Notice how it changes 27:43 to 3:43, and creates the order.
Where I am using it, in this query:
SELECT *,COALESCE(ADDTIME(s.`departure_time`,SEC_TO_TIME(rt.delay)),s.`departure_time`) as `rt_time` FROM `stop_times` s INNER JOIN `trips` t ON s.`trip_id` = t.`trip_id` INNER JOIN `stops` st ON st.`stop_id` = s.`stop_id` INNER JOIN `routes` r ON r.`route_id` = t.`route_id` LEFT JOIN `rt_trips` rt ON t.`trip_id` = rt.`trip_id` where (s.`stop_id` = 'CB900') and ( ( s.`departure_time` >= '00:50' and s.`departure_time` <= '05:50') OR ( s.`departure_time` >= '24:50' and s.`departure_time` <= '29:50') ) and (s.`pickup_type` = '0') and (t.`service_id` IN ('removed to make it easier')) HAVING (`rt_time` BETWEEN '01:50' and '05:50' ) ) OR ( `rt_time` BETWEEN '25:50' and '29:50' ) ORDER BY `order` ASC
Explanation:
Information is a transit schedule, that may go forward onto the next day which may be a saturday. So, times may become 25:50, where that means 1:50 the next day.
Thanks
Cyrus
Hmmm, if you just want to get a value between 0 and 24 hours, then I would do:
select concat(mod(substring_index(time_column, ':', 1) + 0, 24), ':',
substring_index(time_column, ':', -1)
)
Try this function on the time_column
concat(mod(substr(time_column,1,INSTR(time_column, ':')-1),24)
,substr(time_column,INSTR(time_column, ':'),3)
)
You might need to cast date to string to integer, do the maths, and again cast it to time. But the fiddle version seems to work properly on varchar to integer conversion. Check this
http://sqlfiddle.com/#!9/ff60f9/1

Informix Query Where Clause [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Help All,
I am writing a query in Informix and have been stuck on the where clause. I have 2 CSQnames that I want to select and certain times and all others I want to show in between another time. My query ran perfectly until I added this specific where statement. If anyone can offer suggestions I would really appreciate it. I am getting a general error. In Informix since I am unable to put a if then statement in the where clause how would I rewrite my syntax? Thanks!
SELECT
(ccd.nodeid||"-"||ccd.sessionid||"-"||ccd.sessionseqnum) as sequenceID,
ccd.sessionid as sessionid,
ccd.sessionseqnum as sequencenum,
ccd.applicationName as AppName,
csqname as CSQName, ccd.flowout, ccd.conference,
CASE WHEN contacttype=1 THEN "Incoming"
WHEN contacttype=2 THEN "Outgoing"
WHEN contacttype=3 THEN "In House"
WHEN contacttype=4 THEN "Redirect In"
WHEN contacttype=5 THEN "Transfer In"
END as ContactType,
CASE WHEN contactdisposition = 1 THEN "Abandoned"
WHEN contactdisposition = 2 THEN "Handled"
WHEN contactdisposition = 4 THEN "Aborted"
WHEN contactdisposition >= 5 THEN "Rejected"
END as ContactDisposition,
CASE WHEN originatortype=1 THEN "Agent"
WHEN originatortype=2 THEN "Device"
ELSE "Unknown"
END as OriginatorType,
CASE WHEN destinationtype=1 THEN "Agent"
WHEN destinationtype=2 THEN "Device"
ELSE "Unknown"
END as DestinationType,
DATE(ccd.startdatetime) as date,
ccd.startdatetime as starttime,
ccd.enddatetime as endtime,
res.resourcename, ccd.transfer, ccd.redirect,
ccd.originatordn, ccd.destinationdn,
crd.queuetime/86400 as queuetime,
acd.talktime/86400 as TalkTime,
acd.holdtime/86400 as HoldTime,
acd.worktime/86400 as WorkTime
FROM contactcalldetail ccd
Left JOIN contactroutingdetail crd ON crd.sessionID = ccd.sessionID
AND crd.sessionSeqNum = ccd.sessionSeqNum
AND crd.nodeID = ccd.nodeID
AND crd.profileID = ccd.profileID
LEFT JOIN agentconnectiondetail acd ON acd.sessionID = ccd.sessionID
AND acd.sessionSeqNum = ccd.sessionSeqNum
AND acd.nodeID = ccd.nodeID
AND acd.profileID = ccd.profileID
LEFT JOIN resource res ON acd.resourceid = res.resourceid
left join contactqueuedetail cqd on cqd.sessionid=crd.sessionid
left join contactservicequeue csq on cqd.targetid= csq.recordid
WHERE (
ccd.startdatetime BETWEEN '2014-1-2 13:00:00' AND '2016-12-31 22:30:00'
AND (
if (csqname in ("CSQ_Emeriti" , "SOS-Emeriti")
AND EXTEND(ccd.startdatetime, HOUR TO second) > DATETIME(13:30:00) HOUR TO SECOND
AND EXTEND(ccd.startdatetime, HOUR TO second) < DATETIME(22:00:00) HOUR TO SECOND
)
or(csqname not in (“CSQ_Emeriti" , "SOS-Emeriti")
AND
EXTEND(ccd.startdatetime, HOUR TO second) > DATETIME(13:00:00) HOUR TO SECOND
AND EXTEND(ccd.startdatetime, HOUR TO second) < DATETIME(22:30:00) HOUR TO SECOND
)
)
AND WEEKDAY(ccd.startdatetime) BETWEEN 1 AND 5
AND (contacttype IN (1,4,5))
AND ccd.originatordn !='2155870700'
)
If the query is on Informix, if is not available in the WHERE clause of SQL Statement.
If I understood you correctly what you want is:
...
AND (
(
csqname in ("CSQ_Emeriti" , "SOS-Emeriti")
AND EXTEND(ccd.startdatetime, HOUR TO second) > DATETIME(13:30:00) HOUR TO SECOND
AND EXTEND(ccd.startdatetime, HOUR TO second) < DATETIME(22:00:00) HOUR TO SECOND
)
OR
(
csqname not in ("CSQ_Emeriti" , "SOS-Emeriti")
AND EXTEND(ccd.startdatetime, HOUR TO second) > DATETIME(13:00:00) HOUR TO SECOND
AND EXTEND(ccd.startdatetime, HOUR TO second) < DATETIME(22:30:00) HOUR TO SECOND
)
)
...
Keen regards.

MySQL: Use value from table 2 instead of table 1 when exists in table 2

I have a transport planner written in PHP and MySQL,
To get the task rules per day, I use the following query:
SELECT planning.*,
planning_dagen.planning_id,
planning_dagen.dagen,
planning_dagen.data_import,
routenummer_wijzigingen.routenummer AS temp_routenummer
FROM planning
LEFT JOIN planning_dagen
USING (planning_id)
LEFT JOIN routenummer_wijzigingen
USING (planning_id)
WHERE :datum >= planning.datum
AND :datum <= geldig_tot
AND (frequentie = 'dagelijks' AND dayofweek(:datum) = planning_dagen.dagen
OR (frequentie = 'eenmalig' AND date(:datum) = planning.datum)
OR (frequentie = 'wekelijks' AND 0 = (abs(datediff(:datum, planning.datum)) % 7))
OR (frequentie = 'twee-wekelijks' AND 0 = (abs(datediff(:datum, planning.datum)) % 14))
OR (frequentie = 'maandelijks'
AND ceil(dayofmonth(:datum)/7) = ceil(dayofmonth(planning.datum)/7)
AND dayofweek(:datum) = dayofweek(planning.datum)))
AND dayofweek(:datum) <> '1'
AND dayofweek(:datum) <> '7'
In the planning table there is a column called routenummer (routenumber) which is used in most conditions (standard routenumber).
But as you can see I have also a routenummer_wijzigingen table which is used to give a task a different routenumber for certain day.
For example I have a task which returns every tuesday and wednesday and has routenumber 10. But on tuesday 2015-02-03 I need this task done by routenumber 9.
So I insert a rule in the routenummer_wijzigingen table which has the following columns:
routenummer_wijzigingen_id
planning_id
routenummer
datum
So when a date is selected and that date and planning_id exists in the routenummer_wijzigingen table, it has to take the routenumber from the routenummer_wijzigingen table instead of the planning table.
How can I achieve this?
You should modify join condition with routenummer_wijzigingen table (including datum). Then you should use CASE in your SELECT clause to decide which routenummer to choose.
SELECT planning.*,
planning_dagen.planning_id,
planning_dagen.dagen,
planning_dagen.data_import,
CASE
WHEN routenummer_wijzigingen.routenummer is not NULL
THEN routenummer_wijzigingen.routenummer
ELSE planning.routenummer
END AS temp_routenummer
FROM planning
...
LEFT JOIN routenummer_wijzigingen rw on
planning.planning_id=rw.planning_id and rw.datum=...

Assigning a value from another database and function - MySQL variable scope

I am using MySQL to make a report showing the number of hours billed for a particular date range and project. The complexity is that the date range is variable for each project (different start month and start day). This information is coming from a value in another database/table.
I have the following UDF in MySQL:
DELIMITER //
CREATE FUNCTION TimeLeft(startday INT, today INT) RETURNS INT
DETERMINISTIC
BEGIN
DECLARE s INT;
IF startday < today THEN SET s = 0;
ELSE SET s = 1;
END IF;
RETURN s;
END //
DELIMITER;
I use that function in the following query, which is supposed to take the value returned in the TimeLeft function to determine the values for the start month (month(curdate())-#xx) and start day (#yy) for each project to calculate the hours:
AND time_records.record_date >= concat('2012/', month(curdate())-#xx , '/' , #yy)
Here's how I am setting the values for #xx and #yy:
SET #xx = 0; #this is the value that we will use to manipulate the month for the date range
SET #yy = 0;
#yy:= SELECT start_day_of_month FROM dashboard.client; #this doesn't seem to work
SELECT #xx:= TimeLeft(#yy,dayofmonth(curdate()));
I am getting some issues:
#yy is not getting the value - possibly my syntax is wrong?
The variables are set at the top of the code, so they are not getting changed for each project as they should be (there should be a different #xx and #yy for each project since each one has a different start and end date).
Here's the full query:
#below is where I assign the variables
SET #xx = 0; #this is the value that we will use to manipulate the month for the date range
SET #yy = 0;
#yy:= SELECT start_day_of_month FROM dashboard.client; #this doesn't seem to work
SELECT #xx:= TimeLeft(#yy,dayofmonth(curdate()));
# below is the MySQL query that is meant to use the variables assigned above
SELECT X.expr1 AS 'Project Name', #monthly_hours - SUM(X.expr2) AS 'Hours Billed
FROM
(SELECT
projects.name AS expr1
, sum(time_records.value) AS expr2
FROM project_objects
INNER JOIN projects
ON projects.id = project_objects.project_id
INNER JOIN time_records
ON time_records.parent_id = project_objects.id
WHERE time_records.parent_type = 'Task'
AND time_records.record_date >= concat('2012/', month(curdate())-#xx , '/' , #yy)
AND time_records.record_date <= curdate()
GROUP BY projects.name
UNION
SELECT
projects.name AS expr1
, sum(time_records.value) as expr2
FROM projects
INNER JOIN time_records
ON projects.id = time_records.parent_id
WHERE time_records.parent_type = 'Project'
AND time_records.record_date >= concat('2012/', month(curdate())-#xx , '/' , #yy)
AND time_records.record_date <= curdate()
GROUP BY projects.name) X
GROUP BY X.expr1
I think there is some issue of where I am assigning the variables #xx and #yy. These should be done for each individual Project, so putting them up on the top is probably not the best idea. I'm also not sure if I am assigning the #yy value correctly. It's supposed to query the value of the field of a table that is in another database but it keeps throwing a syntax error on the #yy assignment to that field.
Assign value to #yy inside select:
SELECT #yy:= start_day_of_month FROM dashboard.client;