Tsql 查找特定时间段内的总数SQL

Tsql 查找特定时间段内的总数SQL,tsql,count,Tsql,Count,我试图找出在给定时间段内的成员总数。假设我有以下数据: member_id start_date end_date 1 9/1/2013 12/31/2013 2 10/1/2013 11/12/2013 3 12/1/2013 12/31/2013 4 5/1/2012 8/5/2013 5 9/1/2013 12/31/2013 6 7/1/

我试图找出在给定时间段内的成员总数。假设我有以下数据:

member_id   start_date  end_date
1           9/1/2013    12/31/2013
2           10/1/2013   11/12/2013
3           12/1/2013   12/31/2013
4           5/1/2012    8/5/2013
5           9/1/2013    12/31/2013
6           7/1/2013    12/31/2013
7           6/6/2012    12/5/2013
8           10/1/2013   12/31/2013
9           7/8/2013    12/31/2013
10          1/1/2012    11/5/2013
在SQL中,我需要创建一个报告,列出一年中每个月的成员数量。在这种情况下,如下所示:

Date    Members Per Month
Jan-12  1
Feb-12  1
Mar-12  1
Apr-12  1
May-12  2
Jun-12  3
Jul-12  3
Aug-12  3
Sep-12  3
Oct-12  3
Nov-12  3
Dec-12  3
Jan-13  3
Feb-13  3
Mar-13  3
Apr-13  3
May-13  3
Jun-13  3
Jul-13  5
Aug-13  4
Sep-13  6
Oct-13  8
Nov-13  6
Dec-13  6
因此,从1月12日到5月12日,只有1名成员id为10,成员id为4,成员id为2,以此类推


日期范围可以是所有的,所以我不能指定具体的日期,但它是按月计算的,这意味着即使某人12月1日结束,它在12月的当月也被视为活动的。

这应该可以做到

with datesCte(monthStart,monthEnd) as
(
    select cast('20120101' as date) as monthStart, cast('20120131' as date) as monthEnd
    union all
    select DATEADD(MONTH, 1, d.monthStart), dateadd(day, -1, dateadd(month, 1, d.monthStart))
    from datesCte as d
    where d.monthStart < '20140101'
)

select *
from datesCte as d
cross apply
(
    select count(*) as cnt
    from dbo.MemberDates as m
    where m.startDate <= d.monthEnd and m.endDate > d.monthStart
) as x
order by d.monthStart

我能够创建以下存储过程,以完成我需要的任务:

USE [ValueBasedSandbox]
GO

/****** Object:  StoredProcedure [dbo].[sp_member_count_per_month]    Script Date: 01/08/2015 12:02:37 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

-- =============================================
-- Create date: 2015-08-01
-- Description: Find the counts per a given date passed in
-- =============================================
CREATE PROCEDURE [dbo].[sp_member_count_per_month] 
    -- Add the parameters for the stored procedure here
      @YEAR int 
    , @ENDYEAR int 

AS

DECLARE @FIRSTDAYMONTH DATETIME
DECLARE @LASTDAYMONTH DATETIME
DECLARE @MONTH INT = 1;

--Drop the temporary holding table if exists
IF OBJECT_ID('tempdb.dbo.##TEMPCOUNTERTABLE', 'U') IS NOT NULL
    DROP TABLE dbo.##TEMPCOUNTERTABLE

CREATE TABLE dbo.##TEMPCOUNTERTABLE (
      counter INT
    , start_date DATETIME2
    , end_date DATETIME2
    )


--Perform this loop for each year desired
WHILE @YEAR <= @ENDYEAR
BEGIN
    --Perform for each month of the year
    WHILE (@MONTH <= 12)
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;

        SET @FIRSTDAYMONTH = DATEADD(MONTH, @MONTH - 1, DATEADD(YEAR, @YEAR-1900, 0))
        SET @LASTDAYMONTH = DATEADD(MONTH, @MONTH, DATEADD(YEAR, @YEAR-1900, 0)-1)

        INSERT INTO dbo.##TEMPCOUNTERTABLE(counter, start_date, end_date)
        SELECT COUNT(*) AS counter
             , @FIRSTDAYMONTH AS start_date
             , @LASTDAYMONTH AS end_date
          FROM dbo.member_table
         WHERE start_date <= @LASTDAYMONTH
           AND end_date >= @FIRSTDAYMONTH

        --Increment through all the months of the year
        SET @MONTH = @MONTH + 1

    END  -- End Monthly Loop

    --Reset Month counter
    SET @MONTH = 1
    --Increment the desired years
    SET @YEAR = @YEAR + 1

END -- End Yearly Loop


--Display the results
SELECT *
  FROM dbo.##TEMPCOUNTERTABLE

-- Drop the temp table
IF OBJECT_ID('tempdb.dbo.##TEMPCOUNTERTABLE', 'U') IS NOT NULL
    DROP TABLE dbo.##TEMPCOUNTERTABLE

GO

谢谢你的快速回复,保罗!我能够通过创建一个存储过程来完成我需要的任务,该存储过程可以在数年和数月之间循环。我试着把它贴进去,但是太长了。