سؤال

لدي جدول مع البيانات التالية:

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

لكنني في حيرة عندما يتعلق الأمر بإجراء استئجاره لجعل عمل الانضمام.

كيف يمكنني أن أقوم بالانضمام إلى "أكبر أسبوع مالي أصغر من السجل الحالي"؟

هل كانت مفيدة؟

المحلول

أسهل طريقة للقيام بذلك مع 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 - إذا كنت ترغب في تمديد عبور حدود هذه السنة، فستتمكن ببساطة لإسقاط "القسم عن طريق" الشرط "و" 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

نصائح أخرى

هل هذا فعال؟ الاستعلام المضمون قليلا من الفم وربما هناك طريقة أفضل للقيام بذلك ...

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

إذا كنت تستخدم 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

تحرير: لاحظ أنني قمت بتكييف SQL من خلال النظر في مقال ودون IDE.
أيضا، أنا لا أعرف - كيف ستعمل من أجل الصف الأول.

لذلك، يرجى أن تكون لطيف :)

Edit2: اسمحوا لي أن أعرف، إذا لم يعمل على الإطلاق.
هذا سيساعدني في معرفة - وليس للإجابة على الأشياء، دون التحقق من النتائج.

Edit3: لقد قمت بإزالة الحاجة إلى معلمة الربع من الوظيفة.

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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top