SQL中如何按日期范围分组

发布于 2024-11-15 08:38:02 字数 950 浏览 4 评论 0原文

借鉴 StackOverflow.com 的这篇其他帖子我发现这很有用。

我想知道是否可以使用我未明确定义的日期范围进行分组。

为了澄清起见,假设我有一个名为“人员”的表和一个名为“出生日期”的列。

我想对一个时期内出生的人数进行分组和统计。

所以它看起来像这样。

出生计数

Mar1980 25

Apr1980 452

May1980 42

...

Dec1993 452

该期间可以是几周、几个月和几个季度。

如果我使用其他解决方案,我需要指定每个日期范围,即使是月份和年份,也需要很长时间,因为人们的出生日期差异很大。

select t.DOB as [dob], count(*) as [number of occurences]
from (
      select user_id,
         case when date >= '1980-01-01' and date < '1980-02-01 then 'Jan 1980'
         when date >= '1980-02-01' and date < '1980-03-01 then 'Feb 1980'
         ...
         when date >= '1990-03-01' and date < '1990-04-01 then 'Mar 1990'
        else 'Null' end as DOB
     from Person) t
group by t.DOB

您能想到有什么解决方案可以让我指定数据范围的间隔大小并按这些日期范围进行分组吗?

Drawing on from this other post of StackOverflow.com which I found useful.

I was wondering if it is possible to group by using date ranges that I don't explicitly define.

So to clarify, say I have a table called Person and a column called Date Of Birth.

I would like to group by and count the number of people born in a period.

So it would look something like this.

Born Count

Mar1980 25

Apr1980 452

May1980 42

...

Dec1993 452

The period could be weeks, months and quarters.

If I used the other solution, I would need to specify every single date range, even with months and years, it would take a long time as people's date of birth vary a lot.

select t.DOB as [dob], count(*) as [number of occurences]
from (
      select user_id,
         case when date >= '1980-01-01' and date < '1980-02-01 then 'Jan 1980'
         when date >= '1980-02-01' and date < '1980-03-01 then 'Feb 1980'
         ...
         when date >= '1990-03-01' and date < '1990-04-01 then 'Mar 1990'
        else 'Null' end as DOB
     from Person) t
group by t.DOB

Is there any solution you can think of that can allow me to specify just the size of the interval I want the data ranges to be and group by these date ranges?

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

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

发布评论

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

评论(2

删除→记忆 2024-11-22 08:38:02

像这样的东西能满足您的需求吗?诀窍是使用和滥用 CONVERT 函数来获取您的时间段很好地结合在一起,然后使用 DENSE_RANK将其简化为单调递增序列。

WITH DUMMY_DATA AS
(
-- use a convert with a type of 112 to coerce dates to
-- YYYY-MM format and truncate days
-- Be creative, use to generate whatever bands you desire
SELECT CONVERT(char(7), '2011-06-01', 112) AS period, 'stuff' AS junk
UNION ALL SELECT CONVERT(char(7), '2011-05-01', 112) AS period, 'more stuf' AS junk
UNION ALL SELECT CONVERT(char(7), '2011-05-01', 112) AS period, 'more stuf1' AS junk
UNION ALL SELECT CONVERT(char(7), '2011-05-01', 112) AS period, 'more stuf2' AS junk
UNION ALL SELECT CONVERT(char(7), '2011-05-01', 112) AS period, 'more stuf3' AS junk
UNION ALL SELECT CONVERT(char(7), '2011-05-01', 112) AS period, 'more stu4f' AS junk
UNION ALL SELECT CONVERT(char(7), '2011-05-01', 112) AS period, 'more stuf5' AS junk
UNION ALL SELECT CONVERT(char(7), '2011-05-01', 112) AS period, 'more stuf7' AS junk
UNION ALL SELECT CONVERT(char(7), '2011-05-01', 112) AS period, 'more stuf8' AS junk
UNION ALL SELECT CONVERT(char(7), '2011-05-01', 112) AS period, 'more stuf9' AS junk
UNION ALL SELECT CONVERT(char(7), '2011-05-01', 112) AS period, 'more stuf0' AS junk
)
, BANDS AS
(
-- Using our data, create bands in case you want to look
-- at groupings 
SELECT
    D.*
,   DENSE_RANK() OVER (ORDER BY D.period ASC) AS banding
FROM
    DUMMY_DATA D
)
, ROLLUPS AS
(
-- ROll up based on our banding
SELECT
    B.period
,   B.banding
,   COUNT(1) AS row_count
FROM
    BANDS B
GROUP BY
    B.period
,   B.banding


SELECT * FROM ROLLUPS R

使用上面的内容,我得到如下输出

[period]   [band]  [row_count]
2011-05    1       10
2011-06    2       1

Would something like this address what you're after? The trick is to use and abuse the CONVERT function to get your time periods to roll together nicely and then use DENSE_RANK to reduce it to a monotonically increase sequence .

WITH DUMMY_DATA AS
(
-- use a convert with a type of 112 to coerce dates to
-- YYYY-MM format and truncate days
-- Be creative, use to generate whatever bands you desire
SELECT CONVERT(char(7), '2011-06-01', 112) AS period, 'stuff' AS junk
UNION ALL SELECT CONVERT(char(7), '2011-05-01', 112) AS period, 'more stuf' AS junk
UNION ALL SELECT CONVERT(char(7), '2011-05-01', 112) AS period, 'more stuf1' AS junk
UNION ALL SELECT CONVERT(char(7), '2011-05-01', 112) AS period, 'more stuf2' AS junk
UNION ALL SELECT CONVERT(char(7), '2011-05-01', 112) AS period, 'more stuf3' AS junk
UNION ALL SELECT CONVERT(char(7), '2011-05-01', 112) AS period, 'more stu4f' AS junk
UNION ALL SELECT CONVERT(char(7), '2011-05-01', 112) AS period, 'more stuf5' AS junk
UNION ALL SELECT CONVERT(char(7), '2011-05-01', 112) AS period, 'more stuf7' AS junk
UNION ALL SELECT CONVERT(char(7), '2011-05-01', 112) AS period, 'more stuf8' AS junk
UNION ALL SELECT CONVERT(char(7), '2011-05-01', 112) AS period, 'more stuf9' AS junk
UNION ALL SELECT CONVERT(char(7), '2011-05-01', 112) AS period, 'more stuf0' AS junk
)
, BANDS AS
(
-- Using our data, create bands in case you want to look
-- at groupings 
SELECT
    D.*
,   DENSE_RANK() OVER (ORDER BY D.period ASC) AS banding
FROM
    DUMMY_DATA D
)
, ROLLUPS AS
(
-- ROll up based on our banding
SELECT
    B.period
,   B.banding
,   COUNT(1) AS row_count
FROM
    BANDS B
GROUP BY
    B.period
,   B.banding

)
SELECT * FROM ROLLUPS R

Using the above, I get output like

[period]   [band]  [row_count]
2011-05    1       10
2011-06    2       1
恋竹姑娘 2024-11-22 08:38:02

您可能可以使用类似的东西并利用函数 DATEPART

。不要忘记取消注释您要测试的语句。

WITH DummyTable AS (
SELECT '05/01/2011' AS DateOfBirth, 'Peter' AS CustomerName UNION ALL
SELECT '06/02/2011' AS DateOfBirth, 'Bill' AS CustomerName UNION ALL
SELECT '05/01/2011' AS DateOfBirth, 'Charles' AS CustomerName UNION ALL
SELECT '07/13/2010' AS DateOfBirth, 'Maria' AS CustomerName UNION ALL
SELECT '01/01/2009' AS DateOfBirth, 'Theresa' AS CustomerName UNION ALL
SELECT '05/01/2011' AS DateOfBirth, 'Steven' AS CustomerName UNION ALL
SELECT '06/02/2011' AS DateOfBirth, 'Matthew' AS CustomerName UNION ALL
SELECT '07/13/2010' AS DateOfBirth, 'Rachel' AS CustomerName UNION ALL
SELECT '05/01/2011' AS DateOfBirth, 'Molly' AS CustomerName UNION ALL
SELECT '07/13/2010' AS DateOfBirth, 'Alex' AS CustomerName UNION ALL
SELECT '08/01/2009' AS DateOfBirth, 'John' AS CustomerName UNION ALL
SELECT '07/13/2010' AS DateOfBirth, 'Ann' AS CustomerName UNION ALL
SELECT '05/01/2011' AS DateOfBirth, 'Jay' AS CustomerName
) 
--By Month

--SELECT DATENAME(month, DateOfBirth)+DATENAME(year, dateofBirth), COUNT(*)
--FROM DummyTable
--GROUP BY DATENAME(month, DateOfBirth)+DATENAME(year, dateofBirth)


--BY Quarter

--SELECT CAST(DATEPART(QUARTER, DateOfBirth) AS Varchar)+' quarter '+DATENAME(year, dateofBirth), COUNT(*)
--FROM DummyTable
--GROUP BY CAST(DATEPART(QUARTER, DateOfBirth) AS Varchar)+' quarter '+DATENAME(year, dateofBirth)

You could probably use something like that and take advantage of function DATEPART

Please. don't forget to uncomment the statement you want to test.

WITH DummyTable AS (
SELECT '05/01/2011' AS DateOfBirth, 'Peter' AS CustomerName UNION ALL
SELECT '06/02/2011' AS DateOfBirth, 'Bill' AS CustomerName UNION ALL
SELECT '05/01/2011' AS DateOfBirth, 'Charles' AS CustomerName UNION ALL
SELECT '07/13/2010' AS DateOfBirth, 'Maria' AS CustomerName UNION ALL
SELECT '01/01/2009' AS DateOfBirth, 'Theresa' AS CustomerName UNION ALL
SELECT '05/01/2011' AS DateOfBirth, 'Steven' AS CustomerName UNION ALL
SELECT '06/02/2011' AS DateOfBirth, 'Matthew' AS CustomerName UNION ALL
SELECT '07/13/2010' AS DateOfBirth, 'Rachel' AS CustomerName UNION ALL
SELECT '05/01/2011' AS DateOfBirth, 'Molly' AS CustomerName UNION ALL
SELECT '07/13/2010' AS DateOfBirth, 'Alex' AS CustomerName UNION ALL
SELECT '08/01/2009' AS DateOfBirth, 'John' AS CustomerName UNION ALL
SELECT '07/13/2010' AS DateOfBirth, 'Ann' AS CustomerName UNION ALL
SELECT '05/01/2011' AS DateOfBirth, 'Jay' AS CustomerName
) 
--By Month

--SELECT DATENAME(month, DateOfBirth)+DATENAME(year, dateofBirth), COUNT(*)
--FROM DummyTable
--GROUP BY DATENAME(month, DateOfBirth)+DATENAME(year, dateofBirth)


--BY Quarter

--SELECT CAST(DATEPART(QUARTER, DateOfBirth) AS Varchar)+' quarter '+DATENAME(year, dateofBirth), COUNT(*)
--FROM DummyTable
--GROUP BY CAST(DATEPART(QUARTER, DateOfBirth) AS Varchar)+' quarter '+DATENAME(year, dateofBirth)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文