-1

鉴于有两个日期,例如 2012-07-08 和 2013-02-06。我需要统计每个用户每个月的记录。如果在特定月份没有用户的数据,那么它应该返回零。输出应如下所示:-

id name   July-12 August-12 September-12 October-12 November-12 December-12 January-13 February-13
1  John      1        2          0            0         1           1           2      2    
2  David     0        1          0            1         1           1           2      2
3  Marry     2        1          0            0         0           1           2      2
4

2 回答 2

2

cant use BETWEEN即使 BETWEEN 是日期,您也可以inclusive。对于这种情况,最好使用

startdate>='2012-07-08 ' and enddate<=2013-02-06

因为2013-02-06将被视为 2013-02-06 00:00:0012AM

为您的问题尝试此解决方案

DECLARE @temp AS TABLE(Month_Name varchar(25),ContactName varchar(50)) -- newly added

;WITH cte
AS 
(
     SELECT datename(month, @startdate) AS [Month_Name], @startdate AS dat
UNION ALL
     SELECT datename(month, DateAdd(Month, 1, dat)), DateAdd(Month, 1, dat) 
     FROM cte
     WHERE DateAdd(Month, 1, dat) < @enddate

)

INSERT INTO @temp
SELECT c.Month_Name,Cs.username
FROM cte c  CROSS JOIN usertbale Cs
ORDER BY c.Month_Name

SELECT c.Month_Name,c.username,ISNULL(tt.coun,0) as coun
FROM @temp c LEFT JOIN
(
    SELECT  datename(month,OrderDate) AS month_Name
           ,count(OrderID) as coun
           ,ContactName
    FROM tblpublisher p INNER JOIN tbluser  u ON u.userid=p.userid
    GROUP BY month_Name,datename(month,publishdate)
) as tt 
ON c.Month_Name=tt.month_Name AND c.username=tt.username

编辑

在上面的查询中使用pivot,您可以获得与您的问题一样的确切结果 检查这个

于 2013-07-08T10:43:13.110 回答
0

希望您需要以下函数来填充给定条件之间的所有日期,并且您可能需要使用旋转来完成任务。

执行:SELECT * FROM dbo.GetDates('2012-07-08','2013-02-06')

CREATE FUNCTION [dbo].[GetDates](@StartDate DATETIME, @EndDate DATETIME)
RETURNS TABLE AS
RETURN (
WITH 
 N0 AS (SELECT 1 AS N UNION ALL SELECT 1)
,N1 AS (SELECT 1 AS N FROM N0 T1, N0 T2)
,N2 AS (SELECT 1 AS N FROM N1 T1, N1 T2)
,N3 AS (SELECT 1 AS N FROM N2 T1, N2 T2)
,N4 AS (SELECT 1 AS N FROM N3 T1, N3 T2)
,N5 AS (SELECT 1 AS N FROM N4 T1, N4 T2)
,N6 AS (SELECT 1 AS N FROM N5 T1, N5 T2)
,NUMS AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS NUM FROM N6)
SELECT CAST(DATEADD(day,num-1,@StartDate) AS Date) as TheDate
FROM NUMS 
WHERE NUM <= DATEDIFF(day,@StartDate,@EndDate) + 1
);
于 2013-07-08T10:53:08.173 回答