Mysql Decimal division automatically round up - mysql

My Function is
DELIMITER $$;
CREATE FUNCTION get_approved_leaves(f_date date, t_date date,
emp_id bigint, ltp_id int)
RETURNS INT NOT DETERMINISTIC
BEGIN
DECLARE leaves_taken decimal(10,3) DEFAULT 0.000;
SELECT SUM(eld_first+eld_second)/2
INTO leaves_taken
FROM erp_apply_leaves, erp_employee_leave_debts
WHERE al_fk_employees = emp_id
AND al_from >= f_date
AND al_to <= t_date
AND al_fk_leave_type = ltp_id
AND eld_fk_apply_leaves = al_id
AND al_status = 101;
RETURN leaves_taken;
END $$;
DELIMITER ;
When I call
SELECT get_approved_leaves('2017-01-01','2017-12-31',18, 5) as debted
FROM `erp_employee_leave_debts` WHERE 1
It gives the out put : 20
But here SUM(eld_first+eld_second) = 39. So I need to get the output = 19.5

Your function definition is expecting an INT as return value.
And as you are returning leaves_taken value, which is of type DECIMAL(10,3),
SQL Engine is converting it to nearest INTEGER value, to match the return type, and returning.
If you want to keep the original value, better you change the return type of the function.
Example is given below:
CREATE FUNCTION
get_approved_leaves( f_date date, t_date date
, emp_id bigint, ltp_id int )
RETURNS DECIMAL(10,3) NOT DETERMINISTIC

Related

How to return boolean based on number of records in database?

Here's what I've tried. My host is returning an error, "Sorry an unexpected error happened!" .
I want it to return true if there is at least 1 record with combination pdriver_id, ptruck_number, and pdate.
DELIMITER %%
CREATE FUNCTION DriverActiveInTruckByDate(
pdriver_id INT,
ptruck_number INT,
pdate DATETIME
)
RETURNS boolean
DETERMINISTIC
BEGIN
DECLARE inDB INT DEFAULT 0;
SET inDB =
SELECT IF(COUNT(*) >= 1,1,0)
FROM
truck_timeline tl
WHERE 1=1
AND tl.driver_id = pdriver_id
AND tl.truck_number = ptruck_number
AND ((pdate BETWEEN tl.begin_date AND tl.end_date) OR (pdate >= tl.begin_date AND tl.end_date IS NULL))
END
%%
DELIMITER ;
Several fixes are needed:
The function is not DETERMINISTIC. This means the result will always be the same given the same inputs. In your case, the result may be different depending on the data in your truck_timeline table. So I would suggest using READS SQL DATA.
If you use SET variable = SELECT... you must put the SELECT in a subquery:
SET inDB = (SELECT ...);
The current manual recommends using SELECT ... INTO variable instead of SET. See https://dev.mysql.com/doc/refman/8.0/en/select-into.html
The INTO position at the end of the statement is supported as of MySQL 8.0.20, and is the preferred position.
SELECT ... INTO inDB;
The function you show doesn't have a RETURN statement. See https://dev.mysql.com/doc/refman/8.0/en/return.html
There must be at least one RETURN statement in a stored function.
Your Full Code could be like this:
DELIMITER %%
CREATE FUNCTION DriverActiveInTruckByDate(
pdriver_id INT,
ptruck_number INT,
pdate DATETIME
)
RETURNS boolean
DETERMINISTIC
BEGIN
DECLARE inDB INT DEFAULT 0;
SET inDB =
(SELECT IF(COUNT(*) >= 1,1,0)
FROM
truck_timeline tl
WHERE 1=1
AND tl.driver_id = pdriver_id
AND tl.truck_number = ptruck_number
AND ((pdate BETWEEN tl.begin_date AND tl.end_date) OR (pdate >= tl.begin_date AND tl.end_date IS NULL))
);
END %%
DELIMITER ;

How many equal days are between two date ranges, SQL

I have table with date ranges, like this:
DATE DATE2
14.03.2013 17.03.2013
13.04.2013 02.05.2013
I have to create a procedure, that returns day count that is equal to two date ranges, one which is in the table and another one.
Forexample, I have date range in the table like this 14.03.2013 - 17.03.2013 and another one, which is declared in procedure like this 02.03.2013 - 16.03.2013, so in this case day count would be 3, because, both date ranges have dates between 14.03.2013 and 16.03.2013.
suppose your table is called daterange and you have parameters defined #param1 and param2 in your procedure then something on these lines should work:
set #param1 := cast('2013-03-14' as date);
set #param2 := cast('2013-03-16' as date);
select
datediff(least(date2,#param2),#param1)+1
from daterange where #param1 between date1 and date2
See example in sqlfiddle
You should be able to adapt this T-SQL function to MySQL
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fu_RPT_OverlappingDateRangesDays]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[fu_RPT_OverlappingDateRangesDays]
GO
-- ======================================================================================================================
-- Author: Stefan Steiger
-- ALTER date: 11.06.2015
-- Alter date: 11.06.2015
-- Description: Calculate the number of overlapping days in two date-ranges
-- http://stackoverflow.com/questions/20836429/how-to-gets-the-number-of-overlapping-days-between-2-ranges
-- ======================================================================================================================
-- DECLARE #firstStart datetime
-- DECLARE #firstEnd datetime
-- DECLARE #secondStart datetime
-- DECLARE #secondEnd datetime
-- SET #firstStart = '01.01.2015'
-- SET #firstEnd = '31.01.2015'
-- SET #secondStart = '15.01.2014'
-- SET #secondEnd = '15.02.2015'
-- SELECT dbo.fu_RPT_OverlappingDateRangesDays( #firstStart, #firstEnd, #secondStart, #secondEnd )
CREATE FUNCTION [dbo].[fu_RPT_OverlappingDateRangesDays]
(
#firstStart datetime
,#firstEnd datetime
,#secondStart datetime
,#secondEnd datetime
)
RETURNS integer
AS
BEGIN
DECLARE #maxStart datetime
DECLARE #minEnd datetime
DECLARE #interval int
IF #firstStart IS NULL OR #firstEnd IS NULL OR #secondStart IS NULL OR #secondEnd IS NULL
-- RETURN 0
RETURN NULL
IF #firstEnd < #firstStart
RETURN 0
IF #secondEnd < #secondStart
RETURN 0
SET #maxStart = #secondStart
SET #minEnd = #secondEnd
IF #firstStart > #secondStart
SET #maxStart = #firstStart
IF #firstEnd < #secondEnd
SET #minEnd = #firstEnd
-- PRINT #maxStart
-- PRINT #minEnd
--SET #interval = DATEDIFF(DAY, #maxStart, #minEnd) + 1
SET #interval = {fn timestampdiff(SQL_TSI_DAY, #maxStart, #minEnd)} + 1
IF #interval < 0
SET #interval = 0
-- PRINT #interval
RETURN #interval
END
GO

Mysql Table function and view returns null value

I really don't know why my function and view in phpmyadmin returns null instead of DATETIME.
This is my function:
DELIMITER $$
CREATE FUNCTION `return_file`( name varchar(10), number int )
RETURNS datetime
DETERMINISTIC
BEGIN DECLARE transdate DATETIME;
SET trans_date = (SELECT `date` from `sample_table` WHERE `name_ref` = name and `ref_number` = number and `type` = 10);
RETURN trans_date;
END$$
DELIMITER ;
While this is my view:
CREATE VIEW getsME as
SELECT id,type,date,name_ref,ref_number,return_file(name_ref,ref_number) as transDate
FROM sample_table
WHERE type= 11
ORDER BY id ASC

How to declare table in SQL Server?

I am trying to create a function which needs to return a table but even function is not made too and I need to return the resulted table.
My script is like this
create function FNC_getPackageListById(#PkId int )
returns table
as
return
if exists (select Date1, Date2 from PromotionPackage
where PkId = #PkId and Date1 is null and Date2 is null)
begin
select Rate,Remarks,PackageName from Package where PkId=#PkId
end
else
begin
select p.Rate,
p.Remarks,
p.PackageName,
pp.Date1,
pp.Date2
from PromotionPackage pp,
Package p
where pp.PkId=p.PkId and p.PkId=#PkId
end
end
The function called table valued function that returns a table. See this example:
CREATE FUNCTION TrackingItemsModified(#minId int)
RETURNS #trackingItems TABLE (
Id int NOT NULL,
Issued date NOT NULL,
Category int NOT NULL,
Modified datetime NULL
)
AS
BEGIN
INSERT INTO #trackingItems (Id, Issued, Category)
SELECT ti.Id, ti.Issued, ti.Category
FROM TrackingItem ti
WHERE ti.Id >= #minId;
RETURN;
END;

MySql Function Is not giving proper result

I have created mysql function as below
DELIMITER $$
DROP FUNCTION IF EXISTS `GetProductIDFunc`$$
CREATE FUNCTION `GetProductIDFunc`( countryid INT (10) )
RETURNS VARCHAR(200)
BEGIN
declare out_id VARCHAR;
select country_percentage INTO out_id from country_markup where estatus = '1' AND `country_id` REGEXP '[[:<:]]countryid [[:>:]]' limit 1;
RETURN out_id;
END$$
DELIMITER ;
And I have called this function like as below
SELECT GetProductIDFunc( 223 )
but it gave me NULL value instead of 7 which is my expected result value.
Check sample data here for above result [link] http://sqlfiddle.com/#!2/6aa92
Note: IF i replace '[[:<:]]countryid [[:>:]]' with static value like '[[:<:]]223 [[:>:]]' than function return desire result.
Help will be appreciated.
MySQL doesn't substitute values of variables inside of strings. You can form the regular expression using concat, for example:
select country_percentage INTO out_id from country_markup
where estatus = '1' AND `country_id` REGEXP concat('[[:<:]]',countryid,'[[:>:]]')
limit 1;