2

そのため、ユーザーが月末から 18 日後まで予測できるシステムがあります。ただし、月の間、彼らは日ごとに実績を入力しています。

現在の日付が 2012 年 9 月 12 日であるとします。今月の予測は 100 単位で、システムにはすでに 25 単位の実績が入力されています。

10 月 18 日にはまだ達していないので、9 月には 100 単位の予測値があると報告します。ただし、ユーザーは、これまでに入力した 25 単位も表示できるようにしたいと考えています。

レポートには 2 つのメジャーがあり、1 つは実績用、もう 1 つは予測用です。9 月の実績がレポートに表示されるようにすると、125 ユニットという数字が表示されますが、これは明らかに正しくなく、今年の合計も正しくありません。

当月のみ使用され、累積されない新しいメジャー「Transient Actuals」を追加することを検討しましたが、これはおかしいようです!

テクノロジはまったく重要ではないと思いますが、私は SQL Server データベースを使用しており、レポートは Analysis Services キューブです。

確かにこれは一般的な問題でなければなりませんか?


わかりました - スキーマはありますが、非常に複雑で、レポートとデータベース テーブルの間に複数のレイヤーがあります。ただし、簡単な SQL の例を示すことができます。

--Actuals and Forecast Tables
DECLARE @Actuals TABLE (
    [Month] INT,
    Value NUMERIC(19,2));
DECLARE @Forecast TABLE (
    [Month] INT,
    Value NUMERIC(19,2));

--Pretending we are in Month #3 put in some dummy data
INSERT INTO @Actuals VALUES (1, 100);
INSERT INTO @Actuals VALUES (2, 120);
INSERT INTO @Actuals VALUES (3, 10);
INSERT INTO @Forecast VALUES (1, 90);
INSERT INTO @Forecast VALUES (2, 90);
INSERT INTO @Forecast VALUES (3, 90);

--Calculate the latest actuals period (this would usually be time-based)
DECLARE @LatestActualsPeriod INT = 2;

--Now report the data to the user
SELECT
    [Month],
    'Actuals' AS Source,
    Value
FROM
    @Actuals
WHERE
    [Month] <= @LatestActualsPeriod
UNION ALL
SELECT
    [Month],
    'Forecast',
    Value
FROM
    @Forecast
WHERE
    [Month] > @LatestActualsPeriod;

その結果は、次のデータを含むテーブルになります。

Month    Source    Value
1        Actuals   100.00
2        Actuals   120.00
3        Forecast   90.00

では、3 か月目の 10.00 の実績をどこに置くと、合計が不正確になり、同じ月の予測がどこかに表示されるのでしょうか?


わかりました、ジェレミーのおかげで、私は答えを持っていると思います...問題は、レポートに次のようなデータがあることです:

Row Labels  Actual   Forecast Total
2012    23.840  18.840  42.680
2012/Jan    3.580   0.000   3.580
2012/Feb    3.520   0.000   3.520
2012/Mar    4.000   0.000   4.000
2012/Apr    3.350   0.000   3.350
2012/May    3.440   0.000   3.440
2012/Jun    3.090   0.000   3.090
2012/Jul    2.860   0.000   2.860
2012/Aug    0.000   4.990   4.990
2012/Sep    0.000   3.500   3.500
2012/Oct    0.000   4.130   4.130
2012/Nov    0.000   2.710   2.710
2012/Dec    0.000   3.510   3.510
Grand Total 23.840  18.840  42.680

これは Analysis Services キューブであるため、「90 Actual/10 Forecast」のような表示はできません。各セルには数値が含まれている必要があります。ただし、別の解決策があります。2 つのメンバーを持つ新しいディメンションを追加すると、これを使用して表示内容を制御できます。

したがって、新しいディメンションには、「すべてを表示」または「関連性を表示」の 2 つの選択肢があります (名前を変更する必要があるかもしれません)。ユーザーが「すべて表示」メンバーを選択している場合、システムが保持する実績と予測が表示されます。したがって、これは、現在の月までの月の予測と実績、および将来の月の予測のみが含まれるため、それらの合計には意味がないことを意味します。

ただし、ユーザーが「関連性を表示」メンバーを選択すると、完了していない月の実績と将来の月の予測のみが表示されます (上記を参照)。

これは、すべてのレポートにこのディメンションを含める必要があり、ユーザーにメンバーの 1 つを選択するように強制する必要があることを意味します。そうしないと、その数値がまったく無意味になるため、最も洗練されたソリューションではありません。

4

1 に答える 1

1

私はここでたくさんの仮定をしていますが、うまくいけば、これはここで役に立ちます。私はあなたのクエリを受け取り、問題を正しく理解していれば、データを読みやすい方法で表示するという問題に役立つと思われる他の方法をいくつか示しています。

最初の例では、日付を常に月の初日にすると仮定しています。そうでない場合は、少しトリッキーになるか、 を使用DATEPART(MONTH, ...して、INT. 毎月の予測値または実際の値があるとは想定していません。

2 番目の例では、わかりやすくするために、実績のある最新の月までの実績のみを表示することを前提としています。次に、その月以降の予測値と実績 (ある場合) が必要であると仮定します。また、2 番目のクエリには各月の予測値があると想定しています。

これらの仮定のいずれかが正しくない場合は、それを処理するためにクエリをさらに変更できます。

--Actuals and Forecast Tables
DECLARE @Actuals TABLE (
    [Month] DATE,
    Value NUMERIC(19,2));
DECLARE @Forecast TABLE (
    [Month] DATE,
    Value NUMERIC(19,2));

INSERT INTO @Actuals VALUES ('20120801', 100);
INSERT INTO @Actuals VALUES ('20120901', 120);
INSERT INTO @Actuals VALUES ('20121001', 10);
INSERT INTO @Forecast VALUES ('20120801', 90);
INSERT INTO @Forecast VALUES ('20120901', 90);
INSERT INTO @Forecast VALUES ('20121001', 90);

INSERT INTO @Actuals VALUES ('20121101', 50);
INSERT INTO @Forecast VALUES ('20121201', 90);
-- If you can't have an actuals record without a forcast record, remove all the ISNULL'ing except the first ISNULL on the [Actual/Forecast] line
-- and change to LEFT JOIN instead of FULL.
SELECT
    SUBSTRING(CONVERT(VARCHAR, ISNULL(F.[Month], A.[Month]), 103), 4, 999) [Report Month]
    , ISNULL(CAST(A.Value AS VARCHAR(20)), '-') + '/' + ISNULL(CAST(F.Value AS VARCHAR(20)), '-') [Actual/Forecast]
FROM
    @Forecast F
    FULL JOIN @Actuals A
        ON A.[Month] = F.[Month]
ORDER BY
    [Report Month]

DELETE @Actuals
WHERE [Month] = '20121101'
DELETE @Forecast
WHERE [Month] = '20121201'

DECLARE @LatestActualsPeriod DATE = (SELECT MAX([Month]) FROM @Actuals);

SELECT
    [Month] [Report Month]
    , CAST(A.Value AS VARCHAR(20)) + ' Actual' [Units]
FROM
    @Actuals A
WHERE
    A.[Month] < @LatestActualsPeriod

UNION

SELECT
    F.[Month] [Report Month]
    , ISNULL(CAST(A.Value AS VARCHAR(20)), '-') + '/' + CAST(F.Value AS VARCHAR(20)) + ' Actual/Forecasted'
FROM
    @Forecast F
    LEFT JOIN @Actuals A
        ON A.[Month] = F.[Month]
WHERE
    F.[Month] >= @LatestActualsPeriod

PS: 回答にスキーマを入れましたが、それを求める私のコメントには返信しませんでした。好奇心からもう一度質問を振り返らなければ、あなたが質問を編集したことに気付かなかったでしょう。

于 2012-09-12T18:48:14.180 に答える