Комплексное представление SQL для виртуального отображения данных - PullRequest
1 голос
/ 21 декабря 2010

У меня есть таблица со следующей таблицей.

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

0 голосов
/ 20 июня 2014

Наиболее распространенным видом использования является устранение сложности.Например:

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 
0 голосов
/ 21 декабря 2010

Не пробовал, но в соответствии с тем, что сказал Майк:

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

Примечание: это сильно повлияет на производительность.

0 голосов
/ 30 декабря 2010

Спасибо за ваши ответы.Я опробовал RECURSIVE VIEW для вышеуказанного требования и дает правильные результаты (я опасаюсь использования ЦП для больших таблиц, так как это рекурсивно).Итак, вот запасная таблица

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

Тогда мы получим рекурсивныйпредставление, которое рекурсивно объединяет таблицу с тем же представлением, чтобы получить запас каждого часа, перемещенный на один час вверх и дополненный уровнем поступающих данных.

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

Я знаю, что для получения рекурсивной работы потребуется огромный процессор для больших таблиц (мы ограничиваемрекурсия только к 12 уровням, так как данные за 12 часов необходимы для того, чтобы они не переходили в бесконечный цикл).Но я думал, что какое-то тело может использовать это для своего рода построения Иерархии.Я буду искать ответы от вас, ребята, о любых других доступных подходах.Благодарю.Вы можете взглянуть на Рекурсивные виды по ссылке ниже для teradata.http://forums.teradata.com/forum/database/recursion-in-a-stored-procedure

0 голосов
/ 21 декабря 2010

Я сталкивался с подобными проблемами раньше. Часто проще убедиться, что нужные вам данные каким-то образом попадают в базу данных. Возможно, вы сможете автоматизировать его с помощью хранимой процедуры, которая периодически запускается.

Сказав это, вы рассматривали попытку COALESCE () со скалярным подзапросом? (Или любую аналогичную функцию, которую поддерживает ваша dbms.) Я бы попробовал сам и опубликовал SQL, но я ухожу на работу через две минуты.

...