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 到 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

对于没有数据的时间,此查询将所有带库存的时间设为空。我们正在研究 ANSI sql 解决方案,以便它可以用于 Teradata 等数据库。

我在想我错误地使用了分区,或者还有其他方法。我们尝试了 CASE WHEN ,但这需要某种循环来检查一个小时的库存。

4

4 回答 4

0

我以前遇到过类似的问题。确保您需要的数据首先以某种方式进入数据库通常更简单。您可以使用定期运行的存储过程来自动化它。

话虽如此,您是否考虑过使用标量子查询尝试 COALESCE() ?(或者您的 dbms 支持的任何类似功能。)我会自己尝试并发布 SQL,但我将在两分钟内离开工作。

于 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

视图最常见的用途是消除复杂性。例如:

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 回答
0

感谢您的回复。我已经针对上述要求尝试了 RECURSIVE VIEW 并给出了正确的结果(我担心大表的 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
----------------------------------

然后我们将有一个递归视图,该视图以递归方式将表与相同的视图连接起来,以使每小时的 Stock 上移一小时,并附加上递增的数据级别。

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 回答