SQL 组不同计数

发布于 2024-11-06 05:53:41 字数 487 浏览 0 评论 0原文

我有下表,

User ID    Start Date   End Date
-------------------------------------
John Doe   Mar 11 2011  May 28 2011
Robret S   Mar 21 2011  Jun 29 2011
Tina T     Feb 01 2011  August 20 2011

我想显示过去 6 个月有多少人可以使用,即使该月没有人。这怎么可能。我知道我必须进行分组并使用不同的计数。

预期输出:

February  = 1 Resource
March     = 3 Resources
April     = 3 Resources
May       = 3 Resources
June      = 2 Resources
July      = 1 Resource
August    = 1 Resource

I have the following table

User ID    Start Date   End Date
-------------------------------------
John Doe   Mar 11 2011  May 28 2011
Robret S   Mar 21 2011  Jun 29 2011
Tina T     Feb 01 2011  August 20 2011

I want to show how many people I have available for the past 6 months, even if the month has no people. How can this be possible. I know I have to do grouping and use distinct count.

Expected Output:

February  = 1 Resource
March     = 3 Resources
April     = 3 Resources
May       = 3 Resources
June      = 2 Resources
July      = 1 Resource
August    = 1 Resource

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

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

发布评论

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

评论(4

一生独一 2024-11-13 05:53:41
With Calendar As
    (
    Select Cast('20110501' As DateTime) As [Date]
    Union All
    Select DateAdd(m,-1,[Date])
    From Calendar
    Where [Date] > DateAdd(m,-5,'20110501')
    )
Select DateName(m, C.Date) + ' ' + Cast(Year(C.Date) As char(4))
    , Case Count(*)
        When 1 Then Cast(Count(*) As varchar(10)) + ' Resource'
        Else Cast(Count(*) As varchar(10)) + ' Resources'
        End
From Calendar As C
    Left Join MyTable As T
        On C.Date Between T.StartDate And T.EndDate
Group By C.Date

结果:

December 2010   | 1 Resource
January 2011    | 1 Resource
February 2011   | 1 Resource
March 2011      | 1 Resource
April 2011      | 3 Resources
May 2011        | 3 Resources
With Calendar As
    (
    Select Cast('20110501' As DateTime) As [Date]
    Union All
    Select DateAdd(m,-1,[Date])
    From Calendar
    Where [Date] > DateAdd(m,-5,'20110501')
    )
Select DateName(m, C.Date) + ' ' + Cast(Year(C.Date) As char(4))
    , Case Count(*)
        When 1 Then Cast(Count(*) As varchar(10)) + ' Resource'
        Else Cast(Count(*) As varchar(10)) + ' Resources'
        End
From Calendar As C
    Left Join MyTable As T
        On C.Date Between T.StartDate And T.EndDate
Group By C.Date

Results:

December 2010   | 1 Resource
January 2011    | 1 Resource
February 2011   | 1 Resource
March 2011      | 1 Resource
April 2011      | 3 Resources
May 2011        | 3 Resources
‘画卷フ 2024-11-13 05:53:41

您将需要过去 6 个月的现有数据记录,以便可以合并两组数据。您可以在 CTE 中生成过去 6 个月的数据,并对数据进行左连接。即使您没有数据,这也可以让您显示过去 6 个月的情况。

You will need the existing data records for the last 6 months, so that you can merge the two sets of data. You can generate the last 6 months in a CTE and do a left join with your data. That will allow you to show the last 6 months even if you have no data.

那小子欠揍 2024-11-13 05:53:41

我认为你不能使用“简单”的 select 语句(甚至使用 GROUPing 等)来做你想做的事情。以下是我的想法,所以你必须稍微尝试一下,最好阅读Joe Celko 的优秀SQL for Smarties 书籍。

您需要创建第二个表,其中包含所有月份(开始/结束日期)。对于所有类型的类似查询,您只需要一张表,并且它必须包含您感兴趣查询的日期范围内的所有月份:

CREATE TABLE months (id, start DATE, end DATE);

INSERT INTO months (id, start, end) 
          values ( (1, 2011-01-01, 2011-01-31), 
                   (2, 2011-02-01, 2011-02-28), ...);

然后,您可以从用户表到本月表进行 LEFT OUTER JOIN。这将为您提供每个用户每个可用月份的一行,您可以根据需要对其进行分组:

SELECT months.id, COUNT(user.id) 
  FROM months LEFT OUTER JOIN users 
         ON user.start_date < months.end 
        AND user.end_date > months.start 
GROUP BY months.id;

希望有帮助。

I don't think you can do what you want using a "simple" select statement (even using GROUPing etc.) The following is off the top of my head, so you'll have to experiment with it a little, and preferably read Joe Celko's excellent SQL for Smarties book.

You need to create a second table that contains all of your months (start/end dates). You only need one table for all types of similar queries, and it must contain all the months in the date ranges your interested in querying:

CREATE TABLE months (id, start DATE, end DATE);

INSERT INTO months (id, start, end) 
          values ( (1, 2011-01-01, 2011-01-31), 
                   (2, 2011-02-01, 2011-02-28), ...);

You then LEFT OUTER JOIN from your user table to this month table. That will give you a row for each user for each month they were available, which you can GROUP as required:

SELECT months.id, COUNT(user.id) 
  FROM months LEFT OUTER JOIN users 
         ON user.start_date < months.end 
        AND user.end_date > months.start 
GROUP BY months.id;

Hope that helps.

染年凉城似染瑾 2024-11-13 05:53:41
WITH resources AS (
  SELECT
    Date = DATEADD(month, v.number, [Start Date])
  FROM atable t
    INNER JOIN master.dbo.spt_values v ON v.type = 'P'
      AND v.number BETWEEN 0 AND DATEDIFF(month, t.[Start Date], t.[End Date])
)
SELECT
  Month = DATENAME(month, Date),
  ResourceCount = CAST(COUNT(*) AS varchar(30)) +
                  CASE COUNT(*) WHEN 1 THEN ' Resource' ELSE ' Resources' END
FROM resources
WHERE Date > DATEADD(month, -6, DATEADD(day, -DAY(GETDATE()), GETDATE()))
GROUP BY YEAR(Date), MONTH(Date), DATENAME(month, Date)
ORDER BY YEAR(Date), MONTH(Date)
WITH resources AS (
  SELECT
    Date = DATEADD(month, v.number, [Start Date])
  FROM atable t
    INNER JOIN master.dbo.spt_values v ON v.type = 'P'
      AND v.number BETWEEN 0 AND DATEDIFF(month, t.[Start Date], t.[End Date])
)
SELECT
  Month = DATENAME(month, Date),
  ResourceCount = CAST(COUNT(*) AS varchar(30)) +
                  CASE COUNT(*) WHEN 1 THEN ' Resource' ELSE ' Resources' END
FROM resources
WHERE Date > DATEADD(month, -6, DATEADD(day, -DAY(GETDATE()), GETDATE()))
GROUP BY YEAR(Date), MONTH(Date), DATENAME(month, Date)
ORDER BY YEAR(Date), MONTH(Date)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文