如何有效地从临时表中提取多个值?

时间:2019-07-14 18:24:02

标签: sql oracle common-table-expression

我想要做的是根据行号提取各种值并将其存储到变量中,以便以后可以将这些变量用于某些分析。当前,我需要从按顺序输入表格的日期开始的前7行中获取值。使用以下代码,我可以获得所需的特定值:

class Card:
    def __init__(self, suit, val):
        self.suit = suit
        self.value = val

    def __str__(self):
        return f'{self.value} of {self.suit}'


class Hand:
    def __init__(self, cards):
        self.cards = cards

    def __str__(self):
        return ' | '.join(str(card) for card in self.cards)


my_hand = Hand([Card('Spades', 'Ace'), Card('Diamonds', 'King')]) # blackjack!
print(my_hand) # we see: `Ace of Spades | King of Diamonds`

但是,这样做的效率非常低,因为每个变量都重复了这段代码,因此编译时间很长。

我认为也许UNION ALL可能是提高我的代码效率的一种方法,但是当我尝试运行它时,却不断出现编译错误:

WITH tempTable AS
(
    SELECT date, ROUND( SUM(size / 1024 / 1024 ) ) AS Size_Used FROM storageTable
    group by date
    order by date DESC
)
SELECT Size_Used INTO lastRowMinus0Value FROM
(
    SELECT Size_Used, ROWNUM AS rn FROM
    (
        SELECT Size_Used FROM tempTable
        ORDER BY date DESC
    )
)
WHERE rn = lastRowMinus0;

如果任何人都可以就如何以更有效的方式提取值提供一些指导,我将不胜感激。

2 个答案:

答案 0 :(得分:0)

UNION ALL将给出第一个查询和第二个查询的所有行合并的结果。您不能将其结果存储到单独的变量中。

如果您真的想使用UNION ALL,则应采用以下方法:

WITH TEMPTABLE AS (
    SELECT
        DATE,
        ROUND(SUM(SIZE / 1024 / 1024)) AS SIZE_USED
    FROM
        STORAGETABLE
    GROUP BY
        DATE
    ORDER BY
        DATE DESC
)
SELECT
    SUM(CASE ROWNUM
        WHEN LASTROWMINUS0   THEN SIZE_USED
    END),
    SUM(CASE ROWNUM
        WHEN LASTROWMINUS1   THEN SIZE_USED
    END)
INTO
    LASTROWMINUS0VALUE,
    LASTROWMINUS1
FROM
    TEMPTABLE
WHERE
    ROWNUM IN (
        LASTROWMINUS0,
        LASTROWMINUS1
    );

干杯!

答案 1 :(得分:0)

尝试PIVOT

DECLARE
  lastRowMinus0 NUMBER;
  lastRowMinus1 NUMBER;
  lastRowMinus2 NUMBER;
  lastRowMinus3 NUMBER;
  lastRowMinus4 NUMBER;
  lastRowMinus5 NUMBER;
  lastRowMinus6 NUMBER;
BEGIN
  WITH t1 AS (SELECT
                ROUND(SUM("size" / 1024 / 1024)) Size_Used,
                ROW_NUMBER() OVER(ORDER BY "date" DESC) rn
              FROM storageTable
              GROUP BY "date")
  SELECT
    "1", "2", "3", "4", "5", "6", "7"
    INTO lastRowMinus0, lastRowMinus1, lastRowMinus2, lastRowMinus3,
         lastRowMinus4, lastRowMinus5, lastRowMinus6
  FROM (SELECT * FROM t1 WHERE rn < 8) t2
  PIVOT(SUM(Size_Used) FOR rn IN(1, 2, 3, 4, 5, 6, 7)) p;

  DBMS_OUTPUT.PUT_LINE('lastRowMinus0: '||lastRowMinus0||CHR(10)||
                       'lastRowMinus1: '||lastRowMinus1||CHR(10)||
                       'lastRowMinus2: '||lastRowMinus2||CHR(10)||
                       'lastRowMinus3: '||lastRowMinus3||CHR(10)||
                       'lastRowMinus4: '||lastRowMinus4||CHR(10)||
                       'lastRowMinus5: '||lastRowMinus5||CHR(10)||
                       'lastRowMinus6: '||lastRowMinus6);
END;

使用db<>fiddle在线进行测试。