1

次の表の表があります。

----------------------------------
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時間の在庫を表示する必要があります。そして、私は列に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などのデータベースで使用できるようにANSISQLソリューションを検討しています。

パーティションを間違って使用していると思いますが、他の方法はありますか。CASE WHENで試してみましたが、在庫を1時間確認するには、何らかのループが必要です。

4

4 に答える 4

0

私は以前に同様の問題に遭遇しました。そもそも、必要なデータが何らかの形でデータベースに取り込まれるようにする方が簡単な場合がよくあります。定期的に実行されるストアドプロシージャを使用して自動化できる場合があります。

そうは言っても、スカラーサブクエリでCOALESCE()を試すことを検討しましたか?(または、dbmsがサポートする同様の機能。)自分で試してSQLを投稿しますが、2分で仕事に取り掛かります。

于 2010-12-21T14:22:48.983 に答える
0

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

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

注:これはパフォーマンスに大きく影響します。

于 2010-12-21T14:40:46.080 に答える
0

ご回答ありがとうございます。上記の要件についてRECURSIVEVIEWを試しましたが、正しい結果が得られています(再帰的であるため、大きなテーブルの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時間上に移動して、データのレベルを増分して追加します。

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レベルに制限しています)。しかし、ある種の階層構造にこれを使用できる体があると思いました。利用可能な他のアプローチについて、皆さんからの回答をさらに探します。ありがとう。以下のteradataのリンクで再帰ビューを確認できます。 http://forums.teradata.com/forum/database/recursion-in-a-stored-procedure

于 2010-12-30T12:59:59.230 に答える
0

ビューの最も一般的な使用法は、複雑さの除去です。例えば:

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 
于 2014-06-20T14:43:23.653 に答える