SQL 从“年”和“季度”创建日期时间值

发布于 2024-11-08 12:43:27 字数 1344 浏览 0 评论 0原文

我知道与日程相关的里程碑的年份和季度(例如“2010”和“4”),并且我想从中选择/创建一个日期时间。有许多巧妙的方法可以用特定日期的格式(“qq”)来识别季度,但不能反过来(或者有吗?)。这是使用 t-sql / SQL Server。

注意:日期时间应为该季度的最后天。

更新:这是我最终使用 gbn 提供的解决方案,使用 AaronLS 的变量名称,然后根据 Frank Kalis 的建议进行缩短和修饰:-) 测试所有 4 个季度以确保年处理得当。感谢所有回答的人!

DECLARE @TheQuarter INT
DECLARE @theYear INT
-- Note: qq = q = quarter for the datepart
SET @TheQuarter = 1
SET @TheYear = 2011
SELECT DATEADD(YEAR, @TheYear-1900, DATEADD(qq, @TheQuarter, -1))
-- 2011-03-31 00:00:00.000

SET @TheQuarter = 2
SET @TheYear = 2011
SELECT DATEADD(YEAR, @TheYear-1900, DATEADD(qq, @TheQuarter, -1))
-- 2011-06-30 00:00:00.000

SET @TheQuarter = 3
SET @TheYear = 2011
SELECT DATEADD(YEAR, @TheYear-1900, DATEADD(qq, @TheQuarter, -1))
-- 2011-09-30 00:00:00.000

SET @TheQuarter = 4
SET @TheYear = 2011
SELECT DATEADD(YEAR, @TheYear-1900, DATEADD(qq, @TheQuarter, -1))
-- 2011-12-31 00:00:00.000

以下是一些从日期获取季度的问题,但反之则不然: 计算当前季度的最后一天计算季度的最后一天在 SQL Server 中存储季度和年份的最佳方式?< /a>

I know the year and the quarter (e.g. "2010" and "4") for a schedule-related milestone and I want to select/create a datetime from it. There are a number of nifty ways to identify the quarter with formats ("qq") of a particular date, but not to go the other way around (or are there?). This is with t-sql / SQL Server.

Note: the datetime should be for the last day of that quarter.

UPDATE: Here is the solution that I ended up using courtesy of gbn, with AaronLS's variable names and then shortened-and-sweetened with Frank Kalis' suggestion :-) It was important to test for all 4 quarters to make sure the year is handled properly. Thanks to everyone who answered!

DECLARE @TheQuarter INT
DECLARE @theYear INT
-- Note: qq = q = quarter for the datepart
SET @TheQuarter = 1
SET @TheYear = 2011
SELECT DATEADD(YEAR, @TheYear-1900, DATEADD(qq, @TheQuarter, -1))
-- 2011-03-31 00:00:00.000

SET @TheQuarter = 2
SET @TheYear = 2011
SELECT DATEADD(YEAR, @TheYear-1900, DATEADD(qq, @TheQuarter, -1))
-- 2011-06-30 00:00:00.000

SET @TheQuarter = 3
SET @TheYear = 2011
SELECT DATEADD(YEAR, @TheYear-1900, DATEADD(qq, @TheQuarter, -1))
-- 2011-09-30 00:00:00.000

SET @TheQuarter = 4
SET @TheYear = 2011
SELECT DATEADD(YEAR, @TheYear-1900, DATEADD(qq, @TheQuarter, -1))
-- 2011-12-31 00:00:00.000

Here are a few q's that fetch the quarter from the date but not the other way around:
Calculate the Last Day in the CURRENT quarter; Calculate the last day of the quarter; Best way to store quarter and year in SQL Server?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

野味少女 2024-11-15 12:43:27

切勿使用字符串进行日期时间转换:格式、语言等容易出错。

将其保留在日期时间类型中...

Select dateadd(day, -1, 
                       dateadd(year, @year-1900,
                                          dateadd(quarter, @qq, 0)
                                     )
             )

Never use strings for datetime conversions: too much to go wrong with formats, language etc.

Keep it in the datetime type...

Select dateadd(day, -1, 
                       dateadd(year, @year-1900,
                                          dateadd(quarter, @qq, 0)
                                     )
             )
极度宠爱 2024-11-15 12:43:27

看起来你已经找到了解决方案,但只是为了它......
如果您选择不同的基准日期,则可以将整个日期缩短为

SELECT DATEADD(YEAR, @TheYear-1900, DATEADD(qq, @TheQuarter, -1))

因为 0 表示 SQL Server 的基准日期为 01.01.1900(以及一个月的第一天),使用 -1 作为基准日期提前 1 天开始,然后您已经有一个月的最后一天(以及季度末)。然后你只需要完成剩下的日期时间魔法就可以了。

Looks like you've already found your solution, but just for the sake of it...
If you choose a different base date, you can shorten the whole thing to

SELECT DATEADD(YEAR, @TheYear-1900, DATEADD(qq, @TheQuarter, -1))

Since 0 indicates SQL Server's base date of 01.01.1900 (and the first day of a month), using -1 as base date starts off 1 day earlier and then you already have your last day of a month (and end of a quarter). Then you just need to do the rest of the datetime magic and voilà.

夏日落 2024-11-15 12:43:27

只需选择季度中的日期:

select
    case @theQuarter
        when 1 then '3/31/' + cast(@theYear as varchar(4))
        when 2 then '6/30/' + cast(@theYear as varchar(4))
        when 3 then '9/30/' + cast(@theYear as varchar(4))
        when 4 then '12/31/' + cast(@theYear as varchar(4))
    end as quarterDate

编辑:调整为季度的最后一天而不是第一天。

Just choose the date from the quarter:

select
    case @theQuarter
        when 1 then '3/31/' + cast(@theYear as varchar(4))
        when 2 then '6/30/' + cast(@theYear as varchar(4))
        when 3 then '9/30/' + cast(@theYear as varchar(4))
        when 4 then '12/31/' + cast(@theYear as varchar(4))
    end as quarterDate

Edit: Adjusted to be last day of quarter instead of first day.

孤檠 2024-11-15 12:43:27

这基本上得到了下一个季度的第一天,然后减去一个,这样你就得到了你想要的季度的最后一天。 (@theQuarter + 1) 将季度加一,然后 *3 -2 获取该季度的第一个月,% 12 为在第四季度时需要,因为您将 1 加 4 得到 5,这给了您 13,但您实际上想要 1,所以 % 会处理这个问题。

最后,将其全部转换为日期时间后,我们得到了下一个季度的第一天,因此在末尾减去 - 1 以减去一天并获得我们最初输入的季度的最后一天。

declare @theQuarter as int;
set @theQuarter = 4;

declare @theYear as int;
set @theYear = 2009;

select 
cast(
  cast(
        ( (@theQuarter + 1) * 3 - 2) % 12 
  as varchar(2)) 
  + '-01-' 
  + cast( (@theYear + (((@theQuarter + 1) * 3 - 2)/ 12) ) as varchar(4))  
as datetime) - 1 ;

This basically gets the first day of the following quarter, and then subtracts one so that you have the last day of the quarter you wanted. (@theQuarter + 1) adds one to the quarter, then *3 -2 gets the first month of that quarter, and % 12 is required when for the fourth quarter because you add one to 4 to get 5, which gives you 13 but you really want 1, so the % takes care of that.

Finally after casting it all to a date time, we have the first day of the following quarter, thus subtract - 1 at the end to subtract one day and get the last day of the quarter we initially put in.

declare @theQuarter as int;
set @theQuarter = 4;

declare @theYear as int;
set @theYear = 2009;

select 
cast(
  cast(
        ( (@theQuarter + 1) * 3 - 2) % 12 
  as varchar(2)) 
  + '-01-' 
  + cast( (@theYear + (((@theQuarter + 1) * 3 - 2)/ 12) ) as varchar(4))  
as datetime) - 1 ;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文