How to Display 4week per month with condition in sql - mysql

I have this logic but I cant figure out what to do to come up with the results. I want to achieve the results below, the idea is (Ex. month of October 2014), normally it has 5 weeks. If there is a 5th week and days is greater than 3 then consider whole week in the next month else add it to 4th week.
Input:
date range
from: 10-01-2014
to: 11-30-2014
Sample Output:
Date Customer week# Dates covered
10-01-2014 Cust01 1 Oct 01 - Oct 11, 2014
10-08-2014 Cust02 1 Oct 01 - Oct 11, 2014
10-17-2014 Cust02 2 Oct 12 - Oct 18, 2014
10-25-2014 Cust03 3 Oct 19 - Oct 25, 2014
10-31-2014 Cust01 4 Oct 26 - Oct 31, 2014
11-01-2014 Cust01 1 Nov 01 - Nov 08, 2014
11-28-2014 Cust02 4 Nov 23 - Nov 30, 2014
11-30-2014 Cust05 4 Nov 23 - Nov 30, 2014
Thanks

Use datepart(ww,[date]) to get week number in a year, then compare the week number by the begin date of a month.
Below is the detail approach to calculate for one date:
declare #dt date, #month_begin date, #month_end date, #week_of_month int
set #dt='20141031'
set #month_begin = convert(date,(convert(char(6),#dt,112)+'01'))
set #month_end = dateadd(day, -1, dateadd(month,1,#month_begin))
set #week_of_month = datepart(ww,#dt) - datepart(ww,convert(date,(convert(char(6),#dt,112)+'01'))) + 1
select
case when #week_of_month > 4 and datepart(dw,#month_end)>3
then 1
else #week_of_month
end as week,
case when #week_of_month > 4 and datepart(dw,#month_end)>3
then datepart(month,dateadd(month,1,#dt))
else datepart(month,#dt)
end as month

Related

Returning Dates In A Formatted Format (Iteration)

I am trying to create tabs with each tab name being the date of the start of each week in the year. So, "Jan 01" then "Jan 08" then "Jan 14" etc.
Essentially, taking x date then adding +7 days and returning that value as a date 7 days from x date.
function CreateWeekTabs(){
var TotalsSheet = spreadsheet.getSheetByName("Totals");
var StartingWeek = new Date(TotalsSheet.getRange("B1").getValue()); //Typically always "Jan 01" shwon. Cell Formatting is MMM DD. Cell Value is 01/01/2019
var CurrentWeek = new Date();
var NextWeek = new Date();
spreadsheet.toast("Please wait...","Creating Tabs");
for (var WeekNum = 1;WeekNum <= 2;WeekNum++){
var DayIncrease = 7 - (7 * WeekNum); //Should produce 0,7,14,21,28.... So first iteration won't increase any value from Jan 01.
CurrentWeek.setDate(StartingWeek.getDate()+DayIncrease); //E.g. First Iteration = Jan 01 + 0 = Jan 01; Second Iteration = Jan 01 + 7 = Jan 08;
NextWeek.setDate(CurrentWeek.getDate()+7); //Should be +7 days from CurrentWeek Value.
var WeekSheetName = Utilities.formatDate(NextWeek,spreadsheet.getSpreadsheetTimeZone(),"MMM DD"); //Should return the date formatted.
Logger.log(WeekNum+" - "+WeekSheetName);
}
}
With Each Iteration, I intend to create WorkSheets with the First Date of each Week Starting from Value of CurrentWeek
Eg: Jan 01, Jan 08, Jan 15, Jan 22, Jan 29, Feb 05, etc...
UPDATE:
I since changed the code to:
function CreateWeekTabs(){
var TotalsSheet = spreadsheet.getSheetByName("Totals");
var CurrentWeek = new Date(TotalsSheet.getRange("B1").getValue()); //Typically always "Jan 01" shown. Cell Formatting is MMM dd. Cell Value is 01/01/2019
// var CurrentWeek = new Date();
var NextWeek = new Date();
spreadsheet.toast("Please wait...","Creating Tabs");
for (var WeekNum = 1;WeekNum <= 12;WeekNum++){
var DayIncrease = (7 * WeekNum) - 7; //Should produce 0,7,14,21,28.... So first iteration won't increase any value from Jan 01.
CurrentWeek.setDate(CurrentWeek.getDate()+DayIncrease); //E.g. First Iteration = Jan 01 + 0 = Jan 01; Second Iteration = Jan 01 + 7 = Jan 08;
NextWeek.setDate(CurrentWeek.getDate()+DayIncrease+7); //Should be +7 days from CurrentWeek Value.
var WeekSheetName = Utilities.formatDate(NextWeek,spreadsheet.getSpreadsheetTimeZone(),"MMM dd"); //Should return the date formatted.
Logger.log("Week Number: "+WeekNum+" - Current Week: "+Utilities.formatDate(CurrentWeek,spreadsheet.getSpreadsheetTimeZone(),"MMM dd")+" Next Week: "+WeekSheetName);
}
}
and the Log is producing the following as outputs. (so I can see what it's producing for Variables 'CurrentWeek' and 'NextWeek'
[19-06-14 14:40:00:463 EDT] Week Number: 1 - Current Week: Jan 01 Next Week: Jun 08
[19-06-14 14:40:00:464 EDT] Week Number: 2 - Current Week: Jan 08 Next Week: Jun 22
[19-06-14 14:40:00:464 EDT] Week Number: 3 - Current Week: Jan 22 Next Week: Jul 13
[19-06-14 14:40:00:465 EDT] Week Number: 4 - Current Week: Feb 12 Next Week: Aug 09
[19-06-14 14:40:00:466 EDT] Week Number: 5 - Current Week: Mar 12 Next Week: Sep 16
[19-06-14 14:40:00:467 EDT] Week Number: 6 - Current Week: Apr 16 Next Week: Oct 28
[19-06-14 14:40:00:468 EDT] Week Number: 7 - Current Week: May 28 Next Week: Dec 16
[19-06-14 14:40:00:468 EDT] Week Number: 8 - Current Week: Jul 16 Next Week: Feb 10
[19-06-14 14:40:00:469 EDT] Week Number: 9 - Current Week: Sep 10 Next Week: Apr 13
[19-06-14 14:40:00:470 EDT] Week Number: 10 - Current Week: Nov 12 Next Week: Jun 21
[19-06-14 14:40:00:471 EDT] Week Number: 11 - Current Week: Jan 21 Next Week: Sep 06
[19-06-14 14:40:00:471 EDT] Week Number: 12 - Current Week: Apr 07 Next Week: Nov 30
Why the blazes? Current Value is calculating correctly, but the value of Next Week is way off, it should be showing +7 days from Current Week.
Try these:
The first calculates the start of week tab name for this week. You can pick the start of week day Sun-Sat is 0-6. The second calculates the start of week tab name for next week.
function thisWeeksStartOfWeekTabname(sow){
var sow=sow || 1;//Sun-0, Sat=6
var ss=SpreadsheetApp.getActive();
var dt=new Date();
while(dt.getDay()>0) {
dt=new Date(dt.setDate(dt.getDate()-1));
}
dt=new Date(dt.setDate(dt.getDate()+sow));
Logger.log(Utilities.formatDate(dt, Session.getScriptTimeZone(), "MMM dd"));
return Utilities.formatDate(dt, Session.getScriptTimeZone(), "MMM dd");
}
function nextWeeksStartOfWeekTabname(sow){
var sow=sow || 1;//Sun-0, Sat=6
var ss=SpreadsheetApp.getActive();
var dt=new Date();
while(dt.getDay()>0) {
dt=new Date(dt.setDate(dt.getDate()+1));
}
dt=new Date(dt.setDate(dt.getDate()+sow));
Logger.log(Utilities.formatDate(dt, Session.getScriptTimeZone(), "MMM dd"));
return Utilities.formatDate(dt, Session.getScriptTimeZone(), "MMM dd");
}

Get date without offset

I'm using MySQL to store my data. I'm recorded dates with different offset according to each timezone. What is important on those dates are only "effective" time. Here is an example:
date1 = "Thu, 27 Oct 2016 07:00:00 CEST +02:00"
# I want to get 700
date2 = "Thu, 27 Oct 2016 22:00:00 CEST +02:00"
# I want to get 2200
I would like to get these values to compare them with my current time. Then if it's currently "2016-11-17 10:12:00 +0100", I would like to compare on a where clause:
"1012" > "2200"
# or
"1012" > "700"
Here is a fake record value:
# my_table
# | id | my_hour
# | XX | "Thu, 27 Oct 2016 07:00:00 CEST +02:00"
# | XY | "Thu, 27 Oct 2016 22:00:00 CEST +11:00"
Here is my code:
hour = Time.zone.now
# "2016-11-18 21:10:00 +0100"
where("CAST(DATE_FORMAT(my_hour,'%H%i') AS UNSIGNED) < ?", hour.strftime("%H%M").to_i)
# => Get XX record?
Use strftime to format date in Rails.
hour = Time.zone.now
MyTable.where("cast(strftime('%H%M', my_hour) as int) < ?", hour.strftime("%H%M").to_i)
here MyTable is your Model, my_hour is your date column and hour is current time.

To get values from 2D array

I have used this query to retrieve the dates for one particular user's approved leaves -
LeaveRequest.where(user_id: 6).where(status: 1).pluck(:from_date, :to_date)
and I'm getting this array as result -
[[Mon, 12 Sep 2016, Fri, 16 Sep 2016], [Tue, 06 Sep 2016, Tue, 06 Sep 2016], [Thu, 01 Sep 2016, Fri, 02 Sep 2016], [Tue, 30 Aug 2016, Wed, 31 Aug 2016]]
what I want is to fetch all the dates as well as the dates between 12 Sep 2016 and 16 Sep, 2016 (13th 14th and 15th).
I am assuming you mean something like this
require 'date'
#This is to simulate your current Array
current_array = 5.times.map {|n [Date.new(2016,n+1,1).<<(1),Date.new(2016,n+1,1)]}
#map the 2 dates to a Range
new_array = current_array.map{|start_date,end_date| (start_date..end_date)}
new_array.first.class
#=> Range
Calling to_a on the Range will blow it out into all the dates between start_date and end_date
With a rails you could do something like
class LeaveRequest
def self.user_requested_ranges(user_id, status_id)
scoped.
where(user_id: user_id, status: status_id).
pluck(:from_date, :to_date).
map do |from_date, to_date|
#optionally to output the full Array in each Range you could use
#(from_date..to_date).to_a
(from_date..to_date)
end
end
end
Then call as
LeaveRequest.user_requested_ranges(6,1)

Auto-generate custom ID using mysql workbench?

I want it to be in the format of "YYYY-###" where it gives the year and number ### incriminating starting from 1. ex: 2016-001, 2016-002, 2016-003,...
You can use a Numbers/Tally table if you like. I use a UDF to dynamically generate number ranges. As you can see in the function call I set the range from 1 to 12 with an increment of 1
Declare #Table table (SomeField int)
Insert into #Table values
(2015),(2016)
Select StringValue =cast(SomeField as varchar(25))+'-'+right('000'+cast(RetVal as varchar(25)),3)
,SomeField
,RetVal
From #Table A
Join (Select RetVal=cast(RetVal as int) from [dbo].[udf-Create-Range-Number](1,12,1)) B
on (1=1)
Returns
StringValue SomeField RetVal
2015-001 2015 1
2015-002 2015 2
2015-003 2015 3
2015-004 2015 4
2015-005 2015 5
2015-006 2015 6
2015-007 2015 7
2015-008 2015 8
2015-009 2015 9
2015-010 2015 10
2015-011 2015 11
2015-012 2015 12
2016-001 2016 1
2016-002 2016 2
2016-003 2016 3
2016-004 2016 4
2016-005 2016 5
2016-006 2016 6
2016-007 2016 7
2016-008 2016 8
2016-009 2016 9
2016-010 2016 10
2016-011 2016 11
2016-012 2016 12
The UDF
CREATE FUNCTION [dbo].[udf-Create-Range-Number] (#R1 money,#R2 money,#Incr money)
-- Syntax Select * from [dbo].[udf-Create-Range-Number](0,100,2)
Returns
#ReturnVal Table (RetVal money)
As
Begin
With NumbTable as (
Select NumbFrom = #R1
union all
Select nf.NumbFrom + #Incr
From NumbTable nf
Where nf.NumbFrom < #R2
)
Insert into #ReturnVal(RetVal)
Select NumbFrom from NumbTable Option (maxrecursion 0)
Return
End

Haskell: count an enum (Days of week) by an int

I want to create a function for a calender programm, that does the following:
proceed :: Day -> Int -> Day
> proceed Mon 9
Wed
The function proceed should tell me, what weekday it is in 9 days, if today is Monday.
Now I try this:
data Day = Mon | Tue | Wed | Thu | Fri | Sat | Sun deriving Show
next :: Day -> Day
next Mon = Tue
next Tue = Wed
next Wed = Thu
next Thu = Fri
next Fri = Sat
next Sat = Sun
next Sun = Mon
proceed :: Day -> Int -> Day
proceed d a = if a==0 then next d
else proceed (next d) (a-1)
I try :
proceed Mon 9
Thu
But that's wrong, the right answear is Wed!!!!!!!
I don't know where I've made the mistake.
Thanks to bheklilr
if a == 0 then d else proceed (next d) (a-1)
It was only an off by one error!