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

年末まで行くべきです。

上記のクエリから 1 週間だけ出力を取得しています。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 に答える
0

これは、必要に応じて調整できる別のソリューションです。

列の可変セットがないことに注意してください。要件を再質問する必要があるかもしれません。列の可変セットで結果を返すと、実行計画のキャッシュが混乱するだけでなく、その結果を必要とするアプリケーションのデータベース マッピングに問題が生じる可能性があります。

さて、ここで...

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)

週の番号付けの集計、合計の weekSums、および結果を表示するための最終的な選択を確認できます。高速で、実行計画を保存して再利用できます (たとえば、SP にラップされている場合)。

: このスクリプトは動的合体/スタッフィングで終了できますが、絶対に必要でない限り、そのようなアプローチはサポートしていません。

于 2013-07-05T22:40:13.030 に答える