How to get the number of business days using mysql - mysql

I have to find the number of business days using mysql.I am using this query but this is not giving me the correct result
SELECT ((DATEDIFF('2015-05-31', '2015-05-01')) -((WEEK('2015-05-31') - WEEK('2015-05-01')) * 2) -
(case when weekday('2015-05-31') = 6 then 1 else 0 end) - (case when weekday('2015-05-01') = 5 then 1 else 0 end))
as DifD ;
It is giving 19 as output where number of business days should be 20
Somebody please help

Try this!
SET #i=-1;
SELECT SUM(CASE WHEN(WEEKDAY(ADDDATE('2015-05-01', INTERVAL #i:=#i+1 DAY))) < 5 THEN 1 ELSE 0 END) AS `business_days`
FROM `table`
WHERE #i < DATEDIFF('2015-05-31', '2015-05-01');
Hope this answer helps!

drop procedure COUNTWEEKDAYS;
DELIMITER $$
CREATE PROCEDURE COUNTWEEKDAYS (FROMDATE TIMESTAMP, TODATE TIMESTAMP)
begin
declare NOOFWEEKDAYS INTEGER;
set NoOfWeekDays = (datediff(todate, fromdate) + 1)
-((timestampdiff(week, FROMDATE , TODATE) * 2))
-weekday(fromdate)%4
-weekday(todate)%4;
select NOOFWEEKDAYS;
end$$

Related

How to calculate number of days between two dates in Mysql excluding weekends (saturday and sunday)? [duplicate]

This question already has answers here:
MySQL function to find the number of working days between two dates
(39 answers)
Closed 4 years ago.
How do I return the number of days between two dates minus the number of saturday and sundays on that period ?
The DATEDIFF function on mysql gives me the number of days but doesnt exclude the weekends.
Example, I have two columns and want to add a third one that is the differente between the two.
I would appreciate any help.
Try using this
Declare #Date1 Datetime, #Date2 Datetime;
Select #Date1 = '8/1/2018', #Date2 = '8/7/2018'
Select Datediff(dd, #Date1 , #Date2) - (Datediff(wk, #Date1 , #Date2) * 2) -
Case When Datepart(dw, #Date1) = 1 Then 1 Else 0 End +
Case When Datepart(dw, #Date2) = 1 Then 1 Else 0 End
DROP FUNCTION IF EXISTS GetNumberOfDays;
CREATE FUNCTION GetNumberOfDays(P_Date1 varchar(20), P_Date2 varchar(20))
RETURNS int(100)
BEGIN
DECLARE x INT;
DECLARE V_Date1 date;
DECLARE V_Date2 date;
SET V_Date1 := STR_TO_DATE(P_Date1, '%d/%m/%Y');
SET V_Date2 := STR_TO_DATE(P_Date2, '%d/%m/%Y');
SET x := 0;
WHILE V_Date1 <= V_Date2
DO
IF (DAYOFWEEK(V_Date1) != 7 AND DAYOFWEEK(V_Date1) != 1)
THEN
BEGIN
SET x = x + 1;
END;
END IF;
SET V_Date1 := DATE_ADD(V_Date1, INTERVAL 1 DAY);
END WHILE;
RETURN x;
END;
SELECT GetNumberOfDays('01/08/2018', '11/08/2018')

While Loops in MYSQL/PHPMyAdmin with Dates

I am trying to pull a sum from my data that is comparing one month to the next. The below code provides what I need to compare two months but I need to run this over 4 years.
SELECT as_of_date,
Sum(case when `as_of_date` = '2014-02-01' AND disclosure_number IN(
SELECT disclosure_number
FROM `gnma_cohort`
WHERE obp BETWEEN '125001' AND '150000' AND in_the_money BETWEEN '0'
AND '49.999' AND `as_of_date` = '2014-01-01') THEN 1 END) AS '2014-
02-01'
FROM `gnma_cohort`
I am new to MySQL but from what I have read it seems a While loop would be my best option. Below is my attempt at creating the loop but I keep getting errors on my delimiter, is this not the correct format for mysql in PHPMYAdmin? I also do not have the standard ; delimiter in my code that I have seen other examples use, but I never use the ; delimiter in phpmyadmin. Any advice on how to fix my code would be greatly appreciated, thank you!
DELIMITER $$
DROP PROCEDURE IF EXISTS itmdates$$
CREATE PROCEDURE itmdates()
BEGIN
DECLARE startdate DATE
WHILE startdate < '2017-10-01' DO
SELECT as_of_date,
Sum(case when `as_of_date` = startdate AND disclosure_number
IN(
SELECT disclosure_number
FROM `gnma_cohort`
WHERE obp BETWEEN '125001' AND '150000' AND in_the_money
BETWEEN '0' AND '49.999' AND `as_of_date` =
DATE_SUB(startdate, INTERVAL 1 MONTH) THEN 1 END) AS
'startdate'
SET startdate = DATE_ADD(startdate, INTERVAL 1 MONTH)
END WHILE
END$$

Custom auto-increment column

I am making a C# project in which I need help to generate and insert fields like below on MySQL database.
161013001
Where:
16 is Year,
10 is Month,
13 is day
and 001 is auto-increment numbers that reset each days.
Eg.
161012-001
161012-002
161012-002
161013-001
161013-002
161014-001
161014-002
161014-003
161014-004
161014-005
161015-001
please guide me how to make this that ID reset each day and start from 1 after every day.
Here both MySQL & SQL Server Implementation are added,
MySQL:
DROP TEMPORARY TABLE TempDate;
CREATE TEMPORARY TABLE TempDate(
Id VARCHAR(50),
Comments VARCHAR(50)
);
INSERT INTO TempDate(Id,Comments)
SELECT '190630-001', '1'
UNION
SELECT '190630-002', '2'
UNION
SELECT '190701-001', '1'
UNION
SELECT '190701-002', '2'
UNION
SELECT '190701-003', '3';
SET #v_ToDay = '';
SET #v_ToDay = (SELECT date_format(current_date(),'%y%m%d'));
SET #v_TotalByDay = '' ;
SET #v_TotalByDay =(
SELECT CONCAT('000',CAST(CASE WHEN COUNT(1) = 0 THEN 1 ELSE COUNT(1)+1 END as CHAR))
FROM TempDate
WHERE LEFT(Id,6) = #v_ToDay);
SELECT CONCAT(#v_ToDay, '-', CASE WHEN CHAR_LENGTH(RTRIM(#v_TotalByDay)) > 3 THEN RIGHT(#v_TotalByDay,3) ELSE #v_TotalByDay END) as NewIdColumn
SQL Server:
DECLARE #TempDate TABLE(
Id NVARCHAR(50),
Comments NVARCHAR(MAX)
)
INSERT INTO #TempDate(Id,Comments)
SELECT '190630-001', '1'
UNION
SELECT '190630-002', '2'
UNION
SELECT '190701-001', '1'
UNION
SELECT '190701-002', '2'
UNION
SELECT '190701-003', '3'
DECLARE #ToDay NVARCHAR(20) = (SELECT CONVERT(NVARCHAR(6), GETDATE(), 12))
DECLARE #TotalByDay NVARCHAR(20) = ''
SELECT #TotalByDay = '000' + CAST(CASE WHEN COUNT(1) = 0 THEN 1 ELSE COUNT(1)+1 END as NVARCHAR(20) )
FROM #TempDate
WHERE LEFT(Id,6) = #ToDay
SELECT #ToDay + '-' + CASE WHEN LEN(#TotalByDay) > 3 THEN RIGHT(#TotalByDay,3) ELSE #TotalByDay END as NewIdColumn
my situation is little more different then this question ....
i have a legacy database (it's not operational only use for reporting
purpose..)
in this DB transaction table was a auto increment tranx id column.
like 1, 2, 3 ...... but now our new report need meaningful tranx id
(yyMMDD<count of that day>) like this question. so actually i need a
select query to solve this problem.
with the help of #Khairul 's logic i solve my problem ....
i share my solution for other's help....
SELECT
trnx_id, account_id, pay_amount,counter_id, trantime, trandate
FROM(
SELECT
#id:=IF(#prev != t.trandate, #rownum:=1, #rownum:=#rownum+1)
,#prev:=t.trandate
,CONCAT(
SUBSTR(YEAR(t.`trandate`),3) -- year
,IF(LENGTH(MONTH(t.`trandate`))=1,CONCAT('0',MONTH(t.`trandate`)),MONTH(t.`trandate`)) -- month
,IF(LENGTH(DAY(t.`trandate`))=1,CONCAT('0',DAY(t.`trandate`)),DAY(t.`trandate`)) -- day
,IF(LENGTH(#id)=1,CONCAT('000',#id),IF(LENGTH(#id)=2,CONCAT('00',#id),IF(LENGTH(#id)=3,CONCAT('0',#id),#id))) -- count
) AS trnx_id
,t.*
FROM tax_info t ORDER BY t.`trandate`, t.`trantime`
) AS te
and my query result is ..........
After solving my problem i try to solve this question .......
for this i use a trigger for input auto increment custom column ...
my code is below , here my payment column has a custom tranx id ....
DELIMITER $$
DROP TRIGGER tranxidGeneration$$
CREATE
TRIGGER tranxidGeneration BEFORE INSERT ON payment
FOR EACH ROW BEGIN
DECLARE v_tranx_id_on INT;
-- count total row of that day
select IFNULL(COUNT(tranx_id),0)+1 Into v_tranx_id_on from payment where SUBSTR(tranx_id,1,6) = DATE_FORMAT(NOW(), "%y%m%d");
-- set custom generate id into tranx_id column
SET NEW.tranx_id := CONCAT(DATE_FORMAT(NOW(), "%y%m%d"),LPAD(v_tranx_id_on,4,0)) ;
END;
$$
DELIMITER ;

Data range using Between in SQL Server

I am trying to select data in different ranges for a category using IN but not quite sure the syntax
ex: a category has the number 1,3,4 then 20 to 30, then 100 to 110
I use the syntax
Case category =
When categoryId IN (1,3,4, [20-30],[100-110] Then 'Running'
But I received syntax error. How do I do it?
You could use
SELECT
CASE
WHEN EXISTS (SELECT *
FROM (VALUES(1,1),
(3,4),
(20,30),
(100,110)) Ranges(Low, High)
WHERE categoryId BETWEEN Low AND High) THEN 'Running'
END
FROM YourTable
CASE
WHEN categoryId IN (1,3,4) OR
(categoryId >= 20 AND categoryId <= 30) OR
(categoryId >= 100 AND categoryId <= 110)
THEN 'Running'
END
You can write a simple scalar function as i normally do .
CREATE FUNCTION [dbo].[Categoory_Range] (#CategoryID as bigInt)
RETURNS bit AS
BEGIN
Declare #result as bit = 0
-- Need to tack a delimiter onto the end of the input string if one doesn't exist
if(#CategoryID <= 4 and #CategoryID > 0)
begin
set #result = 1
end
else if(#CategoryID >20 and #CategoryID <= 30)
begin
set #result =1
end
else if(#CategoryID > 100 and #CategoryID <= 110)
begin
set #result = 1
end
else
begin
set #result= 0
end
return #result
END
When and where ever you want to use like
Select
Case WHEN [Categoory_Range](CategoryID) > 0 Then 'Running' ELSE 'Whatever' END FROM MyTable.
I love using the functions for you don't have to rewrite this all the time. I normally do it with functions. Check the function above didn't test though. Hope it helps. However if you just want to write it once, you can just want to write once, you can do in the query.
you can try this:
CASE
WHEN CategoryId in (1,3,4) or
(CategoryId between 20 and 30) or
(CategoryId between 100 and 110) THEN 'Running'
END

COUNT(DISTINCT(CASE WHEN looking for function not column? MySQL

Ok. I'm about to give up on this one.
When I run the following query, I get "Error Code: 1305. FUNCTION statpurchase.playerId does not exist". I don't get a line number, but I strongly suspect the COUNT(DISTINCT(WHEN clauses.
The query is attempting to compute the percent of unique playerIds who make a purchase in a given day for a range of time. statpurchase.playerId is a valid column name.
It's a poor man who blames his tools, but I suspect its possibly a parser error similar to this one.
delimiter $$
CREATE PROCEDURE `percentUniquesPurchasing`(in startTime datetime, in endTime datetime, in placeId int)
BEGIN
declare total_uniques int;
declare iOS_uniques int;
declare desktop_uniques int;
declare i datetime;
set i = startTime;
CREATE TEMPORARY TABLE results (
theday datetime,
total float,
iOS float,
desktop float
);
while(i < endTime + INTERVAL 1 DAY) do
select count(distinct(statplaysession.playerId)),
count(distinct(case when touchInterface = 1 then statplaysession.playerId else null end)),
count(distinct(case when touchInterface = 0 then statplaysession.playerId else null end))
into
total_uniques, iOS_uniques, desktop_uniques
from rbxstats.statplaysession
where
statplaysession.start > i and
statplaysession.start < i + INTERVAL 1 DAY and
statplaysession.placeId = placeId;
insert into results (theday, total, iOS, desktop)
select i,
if(total_uniques > 0, count(distinct(statpurchase.playerId)) / total_uniques, 0),
if(iOS_uniques > 0, count(distinct(statpurchase.playerId(case when touchInterface = 1 then statpurchase.playerId end))) / iOS_uniques, 0),
if(desktop_uniques > 0, count(distinct(statpurchase.playerId(case when touchInterface = 0 then statpurchase.playerId end))) / desktop_uniques,0)
from rbxstats.statpurchase where
statpurchase.timestamp > i and
statpurchase.timestamp < i + INTERVAL 1 DAY and
statpurchase.placeId = placeId;
set i = i + INTERVAL 1 DAY;
end while;
select * from results;
drop temporary table results;
END$$
on these 2 lines you try to use statpurchase.playerId as a function, which it doesnt seem to be, its a column in your table
if(iOS_uniques > 0, count(distinct(statpurchase.playerId(case when
if(desktop_uniques > 0, count(distinct(statpurchase.playerId(case when