【问题标题】:Function to return if is first or second half of the month如果是上半月或下半月,则返回函数
【发布时间】:2018-07-31 18:53:14
【问题描述】:

我正在学习 SQL,使用 SQL Server,但我遇到了一个问题......有没有办法创建一个函数,如果是上半月或下半月,则返回一个特定日期。 例如,

如果日期是 01/07/2018 那么 0 原因是上半月

如果日期是 2018 年 7 月 30 日,那么 1 个原因是下半月

我对此没有任何疑问,我真的开始学习了哈哈,对不起! =D

希望我已经足够清楚了^^'

【问题讨论】:

  • 一个内置函数?在我听说过的任何 DMBS 中都没有。
  • 如果您编写并发布查询以确定上半月/下半月,我敢肯定有人可以向您展示如何将其包装在一个函数中。您是否在使用 Oracle、SQL Server、Arcturian Rancid-Raptor 或其他一些数据数据库?当您分享这些信息时,它可以帮助我们帮助您。
  • SQL Server 有一个 DATEPART 函数,它返回日期的一部分,例如月份。这应该会帮助你。
  • 您可以使用DATEPART() 函数获取月份中的日期。我不确定获取每个月最后一天的干净方法,但您可以获取下个月第一天的DATEPART() 天,然后使用DATEADD() 减去一天。因此,获取传递给您的日期的 DATEPART() 月份,然后加一个月,减一天,得到天数,除以 2,然后将该日期与原始日期进行比较。

标签: sql-server function date


【解决方案1】:

你可以在你的函数中尝试类似下面的东西

SELECT CASE
    WHEN DATEPART(d,@Date) <=15 THEN 0
    ELSE 1 END

编辑 你的函数看起来像

Create function MyFunc (@myDate datetime)
Returns smallint
as
BEGIN
DECLARE @MidWeek int
IF (DATEPART(m,@myDate)=2)
  SET @MidWeek = 14 -- Special case for Feb (28 or 29 days)
ELSE
  SET @MidWeek = 15 -- Non feb months (30 or 31 days)

IF (DATEPART(d,@myDate) <= @MidWeek )
BEGIN
  RETURN (0)
END

RETURN (1)

END

【讨论】:

  • 肯定是最简单的方法,但i would check out this blog 是关于日期/时间操作的简写。 2 月份你还需要更多的逻辑,但这是在正确的轨道上。
  • @scsimon 同意,我们需要处理 2 月的案例,编辑我的答案
【解决方案2】:

我会使用计数表和NTILE

--this is your input
declare @myDate datetime = '20180413'


--we get the first and last day of that month
declare @startdate datetime = DATEADD(month, DATEDIFF(month, 0, @myDate), 0)
declare @enddate datetime = Dateadd(day,-1,DATEADD(month,1,DATEADD(month, DATEDIFF(month, 0, @myDate), 0)))

--get a tally table of numbers to build our cte of dates for the entire month
;WITH
    E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
    E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
    cteTally(N) AS 
    (
        SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E2
    ),

--create the list of dates
dateRange as(
select theDate = @startdate
union
select dateadd(day,N,@startdate)
from cteTally
where dateadd(day,N,@startdate) <= @enddate)


--use NTILE to separate these into 2 groups
select 
    theDate
    ,half_of_month = ntile(2) over (order by theDate)
into #myDates
from dateRange
order by theDate
--this is just to show how ntile works
select * from #myDates


--return the one for your input
select 
    @myDate
    ,half_of_month = case when half_of_month = 1 then 'First' else 'Second' end
from #myDates
where theDate = @myDate

drop table #myDates

Docs on the NTILE function

【讨论】:

    【解决方案3】:

    如果您将 15 日视为月中

    示例

    Select sign(DatePart(DAY,'2018-07-04')/15)
          ,sign(DatePart(DAY,'2018-07-16')/15)
    

    【讨论】:

    • 2 月份呢?还有闰年?不过我喜欢这个。
    • @scsimon 我们可以玩得开心,在 BOM 和 EOM 之间进行插值,得到准确的值 :)
    • 我可以挖掘它,乔恩,我和 NTILE 一起去了...从我的戈登记忆库里偷了它,哈哈
    【解决方案4】:

    这非常难看,但它会为您提供所需的内容,并且不需要查找表。它也可以处理具有可变天数的月份。

    DECLARE @InputDate datetime; SET @InputDate = GETDATE();
    
    SELECT CASE WHEN @InputDate > DATEADD(DAY, DATEPART(DAY, DATEADD(DAY, -1, DATEADD(MONTH, 1,DATEADD(DAY, ((DATEPART(DAY, @InputDate))*-1)+1, CAST(@InputDate as date))))) / 2, DATEADD(DAY, ((DATEPART(DAY, @InputDate))*-1)+1, CAST(@InputDate as date))) THEN 1 ELSE 0 END AS [MoreThanHalf]
    

    【讨论】:

      【解决方案5】:

      这里没有创建表格,而是使用一个函数将当月的当前日期与当月的最后一天进行比较。如果大于 0.5,那么它将是第二个半月。

      例如:

      1. 1 月 15 日 (15/31) 是
      2. 2 月 15 日(15 月 28 日)>.5,因此第二个一半
      3. 4 月 15 日 (15/30) = 0.5,因此上半场

        create function PortionOfMonth(@d date)
        returns int
        as
        begin
        declare @returnValue int
        
        if cast(day(@d) as decimal(4,2))  --Convert to decimal for division of ints
            /cast( day(dateadd(d,-1, --last day of current month
                            (dateadd(month,1, --1st day of next month
                                    cast(cast(month(@d) as varchar(2)) +'/1/' + cast(year(@d) as varchar(4)) as date))))) --1st day of current month
                                     as decimal(4,2)) --Convert to decimal for division of ints
                                     > .5 
        begin 
            set @returnValue = 1 -- 2nd half
        end
        else 
        begin 
            set @returnValue = 0 --1st half
        end
        
        return @returnValue
        end
        

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-01-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-01
        • 2017-05-06
        相关资源
        最近更新 更多