0

次のデータを含むテーブルがあります。

Fiscal Year | Fiscal Quarter | Fiscal Week | Data
2009        | 2              | 22          | 9.5
2009        | 2              | 24          | 8.8
2009        | 2              | 26          | 8.8
2009        | 3              | 28          | 8.8
2009        | 3              | 31          | 9.1
2009        | 3              | 33          | 8.8

以下を生成するクエリを書きたいと思います。

Fiscal Year | Fiscal Quarter | Fiscal Week | Data | Trend
2009        | 2              | 22          | 9.5  | NULL
2009        | 2              | 24          | 8.8  | -0.7
2009        | 2              | 26          | 8.8  | 0
2009        | 3              | 28          | 8.8  | 0
2009        | 3              | 31          | 9.1  | 0.3
2009        | 3              | 33          | 8.8  | -0.3 

これは、テーブルを前の会計週と簡単に結合することで簡単に実現できますがt1.[Fiscal Week] = t2.[Fiscal Week] - 2、違いが 3 週間ある場合があるため、必ずしも簡単ではありません。

次のようなもので簡単に最大レコードを取得できます。

SELECT
    MAX(t1.[Fiscal Week]) "LastWeek"
FROM t1
WHERE t1.[Fiscal Year] = 2009
    AND t1.[Fiscal Week] < 31

しかし、結合を機能させるためにそれを抽象化することになると、私は途方に暮れています。

「現在の記録よりも小さい最大の会計週」で自己結合を行うにはどうすればよいですか?

4

4 に答える 4

3

Sql 2005+ でこれを行う最も簡単な方法は、ランキング関数とウィンドウ関数を使用することです。データを分割/順序付けし、各レコードに適切なシーケンスを割り当てるだけです (この場合、そのウィンドウで、fiscalYear で分割し、fiscalWeek で順序付けています) -次のようになります。

with data as
(
    select  row_number() over (partition by a.fiscalYear order by a.fiscalWeek) as rn,
            a.fiscalYear, a.fiscalQuarter, a.fiscalWeek, a.Data
    from    #TableName a
)
select  a.fiscalYear, a.fiscalQuarter, a.fiscalWeek, a.Data, 
        a.Data - b.Data as Trend
from    data a
left join data b
on      a.fiscalYear = b.fiscalYear
and     a.rn = b.rn + 1
order by a.fiscalYear, a.rn

この特定のクエリでは、fiscalYear の境界を越えて拡張することはできません。これらの年の境界を越えて拡張したい場合は、"partition by" 句と "fiscalYear" 結合条件を削除し、代わりに、fiscalYear の組み合わせでセットを並べ替えます。そしてfiscalWeekは、次のようになります。

with data as
(
    select  row_number() over (order by a.fiscalYear + a.fiscalWeek) as rn,
            a.fiscalYear, a.fiscalQuarter, a.fiscalWeek, a.Data
    from    #TableName a
)
select  a.fiscalYear, a.fiscalQuarter, a.fiscalWeek, a.Data, 
        a.Data - b.Data as Trend
from    data a
left join data b
on      a.rn = b.rn + 1
order by a.rn
于 2009-12-03T20:16:34.650 に答える
1

SQL Server 2005 を使用している場合は、CROSS APPLY句を使用できます。

ここでは、現在の行の前の会計週の行を返すテーブル値関数を使用できます。

CREATE FUNCTION dbo.fn_GetFiscalWeekBeforeThis(@Year AS int, 
  @CurrentWeek as int)
  RETURNS TABLE
AS
RETURN
  SELECT TOP 1 *
  FROM t1
  WHERE [Fiscal Year] = @Year 
  AND [Fiscal Week] < @CurrentWeek
  ORDER BY [Fiscal Week] DESC
GO

その後、

SELECT A.*,
A.Data - B.Data
FROM
t1 A
CROSS APPLY 
   dbo.fn_GetFiscalWeekBeforeThis(A.[Fiscal Year],  
   A.[Fiscal Week]) AS B

編集:記事を見て、IDE なしで SQL を調整したことに注意してください。
また、わかりません-最初の行でどのように機能するか。

だから、親切にしてください:)

EDIT2: まったく機能しない場合はお知らせください。
これは、結果を確認せずに物事に答えるのではなく、知るのに役立ちます。

EDIT3: 関数から Quarter パラメーターの必要性を削除しました。

于 2009-12-03T20:10:59.367 に答える
1

これは機能しますか?インライン クエリはちょっと面倒ですが、おそらくもっと良い方法があります...

select
  [fiscal year]
, [fiscal quarter]
, [fiscal week]
, [data] 
, (
    select top 1 (i.data - t1.data) from t1 as i
    where i.[fiscal year] >= t1.[fiscal year]
    and i.[fiscal quarter] >= t1.[fiscal quarter]
    and i.[fiscal week] >= t1.[fiscal week]
    and (
          i.[fiscal year] <> t1.[fiscal year]
       or i.[fiscal quarter] <> t1.[fiscal quarter]
       or i.[fiscal week] <> t1.[fiscal week]
    )
    order by [fiscal year] asc, [fiscal quarter] asc, [fiscal week] asc
) as trend
from t1
于 2009-12-03T20:11:06.673 に答える
1
DECLARE @Fiscal TABLE
  ( 
   FiscalYear int
  ,FiscalQuarter int
  ,FiscalWeek int
  ,[Data] decimal(4,1) 
  )

INSERT INTO @Fiscal
          ( FiscalYear, FiscalQuarter, FiscalWeek, [Data] )
SELECT 2009, 2, 22, 9.5 UNION
SELECT 2009, 2, 24, 8.8 UNION
SELECT 2009, 2, 26, 8.8 UNION
SELECT 2009, 3, 28, 8.8 UNION
SELECT 2009, 3, 31, 9.1 UNION
SELECT 2009, 3, 33, 8.8 UNION
SELECT 2010, 1, 1, 9.0 UNION
SELECT 2010, 1, 2, 9.2

;
WITH  abcd
        AS ( SELECT FiscalYear
                   ,FiscalQuarter
                   ,FiscalWeek
                   ,[Data]
                   ,row_number() OVER ( ORDER BY FiscalYear, FiscalWeek ) AS rn
             FROM   @Fiscal
           )
  SELECT  a.FiscalYear
         ,a.FiscalQuarter
         ,a.FiscalWeek
         ,a.[Data]
         ,a.[Data] - b.[Data] AS [Trend]
  FROM    abcd AS a
          LEFT JOIN abcd AS b ON b.rn = ( a.rn - 1 )
  ORDER BY a.FiscalYear
         ,a.FiscalWeek
于 2009-12-03T20:47:26.407 に答える