質問

次のテーブルのあるテーブルがあります。

----------------------------------
Hour    Location        Stock
----------------------------------
6        2000           20
9        2000           24
----------------------------------

したがって、これは、量に変化がある時間の一部に対して在庫を示しています。ここで、私の要件は、このテーブルのビューを作成することです。これは、データを事実上表示することです(特定の時間の在庫がない場合)。したがって、表示されるべきデータは次のとおりです

----------------------------------
Hour    Location        Stock
----------------------------------
6        2000           20
7        2000           20             -- same as hour 6 stock
8        2000           20             -- same as hour 6 stock
9        2000           24
----------------------------------

つまり、特定の時間の間データが存在しなくても、在庫を持っている最後の1時間の在庫を表示する必要があります。そして、私は列に1〜23から利用可能な時間をすべて含む別のテーブルを持っています。

以下に示すように、メソッドごとにパーティションを試しました。しかし、私は自分の要件を成し遂げるために、この周りに何かを見逃していると思います。

SELECT
HOUR_NUMBER,
CASE WHEN TOTAL_STOCK IS NULL
THEN SUM(TOTAL_STOCK)
OVER (
PARTITION BY LOCATION
ORDER BY CURRENT_HOUR ROWS  1 PRECEDING 
)
ELSE
TOTAL_STOCK
END AS FULL_STOCK
FROM 
(
    SELECT HOUR_NUMBER AS HOUR_NUMBER
    FROM HOURS_TABLE -- REFEERENCE TABLE WITH  HOURS FROM 1-23
    GROUP BY 1
) HOURS_REF
LEFT OUTER JOIN
(
SEL CURRENT_HOUR  AS CURRENT_HOUR 
, STOCK AS TOTAL_STOCK
,LOCATION AS LOCATION
FROM STOCK_TABLE
WHERE STOCK<>0
) STOCKS
ON HOURS_REF.HOUR_NUMBER = STOCKS.CURRENT_HOUR

このクエリは、データなしで時間のnullとして在庫を備えたすべての時間を与えています。 Teradataなどのデータベースで使用できるように、ANSI SQLソリューションを検討しています。

私は誤ってパーティションを使用していると考えています。私たちはケースで試しましたが、それはある種のループを必要として、在庫で1時間再度チェックします。

役に立ちましたか?

解決 3

ご回答ありがとうございます。私は上記の要件について再帰的な見解を試しましたが、正しい結果をもたらしています(再帰的であるため、大きなテーブルのCPU使用について恐れています)。ここにストックテーブルがあります

----------------------------------
Hour    Location        Stock
----------------------------------
6        2000           20
9        2000           24
----------------------------------

次に、このテーブルにビューがあり、左外の結合を使用して12時間すべてのデータを提供します。

----------------------------------
Hour    Location        Stock
----------------------------------
6        2000           20
7        2000           NULL
8        2000           NULL
9        2000           24
----------------------------------

次に、同じビューでテーブルに再帰的に結合する再帰ビューがあり、各1時間の在庫を1時間上げて、データレベルのデータを増加させます。

REPLACE RECURSIVE VIEW HOURLY_STOCK_VIEW
(HOUR_NUMBER,LOCATION, STOCK, LVL) 
AS
(
    SELECT
    HOUR_NUMBER,
    LOCATION,
    STOCK,
    1 AS LVL
    FROM STOCK_VIEW_WITH_LEFT_OUTER_JOIN
    UNION ALL
    SELECT
    STK.HOUR_NUMBER,
    THE_VIEW.LOCATION,
    THE_VIEW.STOCK,
    LVL+1 AS LVL
    FROM STOCK_VIEW_WITH_LEFT_OUTER_JOIN STK
    JOIN
    HOURLY_STOCK_VIEW  THE_VIEW
    ON THE_VIEW.HOUR_NUMBER = STK.HOUR_NUMBER -1
    WHERE LVL <=12
)
;

最初に左外の結合ビューから選択し、それを作成している左外の結合ビューと結合し、作成している同じビューで結合され、データが来るレベルを提供します。

次に、このビューから最小レベルでデータを選択します。

SEL * FROM HOURLY_STOCK_VIEW 
WHERE
(
    HOUR_NUMBER,
    LVL
)
IN
(
    SEL 
    HOUR_NUMBER, 
    MIN(LVL)
     FROM HOURLY_STOCK_VIEW
    WHERE STOCK IS NOT NULL
    GROUP BY 1
)
;

これは正常に動作し、結果を与えています

----------------------------------
Hour    Location        Stock
----------------------------------
6        2000           20
7        2000           20             -- same as hour 6 stock
8        2000           20             -- same as hour 6 stock
9        2000           24
10        2000           24
11        2000           24
12        2000           24
----------------------------------

これは、再帰作業を取得するために大きなテーブルに巨大なCPUを取ることを知っています(12時間のデータが無限ループに入るのを止めるために12時間のデータが必要であるため、再帰を12レベルに制限しています)。しかし、ある種の階層ビルにこれを使用できると考えました。利用可能な他のアプローチについて、皆さんからのいくつかの応答を探します。ありがとう。 Teradataの以下のリンクで再帰ビューを見ることができます。http://forums.teradata.com/forum/database/recursion-in-a-stored-procedure

他のヒント

以前にも同様の問題に遭遇しました。しばしば、必要なデータがどうにかしてデータベースに入ることを確認するのが簡単です。定期的に実行されるストアドプロシージャで自動化できる場合があります。

そうは言っても、スカラーサブクエリでcoales()を試すことを考えましたか? (またはDBMSがサポートする同様の機能。)私はそれを自分で試してSQLを投稿しますが、2分で仕事のために出発します。

試したことはありませんが、マイクが言ったことの線に沿って:

SELECT a.hour
     , COALESCE( a.stock
               , (  select b.stock 
                    from   tbl.b 
                    where  b.hour=a.hour-1   )
               ) "stock"
FROM   tbl a

注:これはパフォーマンスに大きな影響を与えます。

視野の最も一般的な用途は、複雑さの除去です。例えば:

CREATE VIEW FEESTUDENT
    AS
    SELECT S.NAME,F.AMOUNT FROM STUDENT AS S
    INNER JOIN FEEPAID AS F ON S.TKNO=F.TKNO

今やる SELECT:

SELECT * FROM FEESTUDENT 
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top