1

我正在尝试每周获取报告,以了解实际使用该产品的人数的状态。

这是我当前的查询

select 
COUNT(*) as 'TotalPurchased',
SUM(case when date<= DATEADD(day, -7, GETDATE())THEN 1 ELSE 0 END) as 'week1' 
from #myreport

我希望输出为

Totalpurchased   week1  week2 week3 ..........so on
  82              80     14    16

它应该到年底。

我从上述查询中仅获得一周的输出。我正在使用 sql 2008 r2 环境从临时表中获取数据。

4

4 回答 4

8

PIVOT如果您想返回列,则可以使用动态 sql 并执行此操作:

DECLARE @cols AS VARCHAR(8000),
    @query  AS VARCHAR(8000)

SELECT @cols = STUFF((SELECT ',' +   QUOTENAME(YrWeek) 
                    FROM (SELECT DISTINCT CAST(YEAR(rpt_dt)AS VARCHAR(4)) + '-' + CAST(DATEPART(week,rpt_dt)AS VARCHAR(2))'YrWeek'
                          FROM #myreport
                          WHERE rpt_dt > DATEADD(YEAR,-1,GETDATE()))sub
                    ORDER BY LEFT(YrWeek,4) DESC,RIGHT(YrWeek,2)DESC
                   FOR XML PATH(''), TYPE
            ).value('.', 'VARCHAR(MAX)') 
        ,1,1,'')

SET @query = 'SELECT * FROM
                (
                SELECT CAST(YEAR(rpt_dt)AS VARCHAR(4)) + ''-'' + CAST(DATEPART(week,rpt_dt)AS VARCHAR(2)) YrWeek, COUNT(*)CT
                FROM #myreport   
                GROUP BY CAST(YEAR(rpt_dt)AS VARCHAR(4)) + ''-'' + CAST(DATEPART(week,rpt_dt)AS VARCHAR(2))
                ) AS T1
                PIVOT (SUM(CT) FOR YrWeek IN ('+@cols+')) AS T2

'
EXEC(@query)

在这个例子中,它在去年每周都在拉动,从今天开始向后拉。

这是一个演示,仅使用日期列表并计算该日期的记录数,我认为这与您最终要做的事情相同。

SQL小提琴

于 2013-07-05T19:47:47.380 回答
2

尝试这样的事情(您可能需要根据需要调整日期范围):

SELECT
    COUNT(*) AS 'count',
    CONVERT(nchar(4), DATEPART(year, [date]))
     + '-' + 
    CONVERT(nchar(2), DATEPART(wk, [date])) AS 'week'
FROM #myreport
WHERE
    [date] BETWEEN GETDATE() AND DATEADD(week, 52, GETDATE())
GROUP BY
    CONVERT(nchar(4), DATEPART(year, [date]))
     + '-' + 
    CONVERT(nchar(2), DATEPART(wk, [date]))
WITH ROLLUP

数据以行而不是列的形式返回。数据库查询以这种方式工作,尝试将数据强制放入动态列是非常不切实际的。您只能求助于康拉德所说的,或者使用动态 sql(使用 while 循环构建字符串)来做同样的事情。我不会那样做。

WITH ROLLUP将简单地添加另一行,'Week' = NULL,总和为'Count'。

于 2013-07-05T19:46:45.987 回答
1

试试这个每周报告

SELECT 
    FLOOR((DATEDIFF(DAY, 'YourStartDate', [DateColumn])) / 7) + 1 AS [Week], 
    CAST(CAST(DATEADD(WEEK, FLOOR((DATEDIFF(DAY, 'YourStartData', [DateColumn])) / 7), 'YourStartData') AS DATE) AS NVARCHAR(16)) + ' - ' + 
    CAST(CAST(DATEADD(DAY, FLOOR((DATEDIFF(DAY, 'YourStartData', [DateColumn])) / 7) * 7 + 6, 'YourStartData') AS DATE) AS NVARCHAR(16)) AS [Range], 
    COUNT(*) AS [TotalPurchased] 
FROM 
    [Table] WITH (NOLOCK) 
GROUP BY 
    FLOOR((DATEDIFF(DAY, 'YourStartDate', [DateColumn])) / 7) 
ORDER BY 
    FLOOR((DATEDIFF(DAY, 'YourStartDate', [DateColumn])) / 7) + 1 

结果将显示:周数、范围(从 YourStartDate - 最多 7 天)和 TotalPurchased。您还可以使用 CAST(GETDATE() as date) 作为参数而不是 'YourStartDate'

于 2015-02-11T13:33:27.400 回答
0

This is just another solution that you can tailor as you wish.

Note that there isn't a variable set of columns. Maybe you should re-question your requirements. Returning a result with variable set of columns will not just mess with your execution plan caching, it can represent a problem to your database mapping in application that needs that result.

Well, here it goes...

DECLARE @start datetime = '2012-6-1'

;WITH tally AS (
  SELECT TOP 52 -- change this if you want more or less than a year of data
    N = row_number() OVER(ORDER BY (SELECT 0)) - 1
  FROM master.dbo.syscolumns sc1)
,weekSums AS (
  SELECT 
    N,
    val = 
      (SELECT COUNT(*) -- Can be ISNULL(SUM(amount), 0) or something else
      FROM #myreport
      WHERE [date] > DATEADD(dd, N * 7, @start) AND at <= DATEADD(dd, (N + 1) * 7, @start))
  FROM tally)
SELECT
  totalPurchased = (SELECT sum(val) FROM weekSums),
  week1 = (SELECT val FROM weekSums WHERE N = 0),
  week2 = (SELECT val FROM weekSums WHERE N = 1),
  week3 = (SELECT val FROM weekSums WHERE N = 2),
  ...
  week52 = (SELECT val FROM weekSums WHERE N = 51)

You can see tally for week numbering, weekSums for summing it up and final select to show the results. It is fast, execution plan can be saved and reused (e.g. when wrapped in SP).

NOTE: This script CAN be finished with dynamic coalescing/stuffing but I don't support that kind of approach if not absolutely necessary.

于 2013-07-05T22:40:13.030 回答