简体   繁体   中英

How do I efficiently extract multiple values from a temporary table?

What I'm trying to do is to extract various values according to their row number and store them into variables, so that these variables can be used later for some analyses. Currently I need to get the values from the first 7 rows ordered by the date they were entered into the table. Using the following code I can get a specific value that I need:

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;

But doing it this way has turned out to be very inefficient as this code is duplicated for each variable, and so it takes a long time to compile.

I thought maybe UNION ALL may be the way to go in order to make my code more efficient, but I keep getting compilation errors when I try and run it:

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 tempTable
WHERE ROWNUM = lastRowMinus0
UNION ALL
SELECT Size_Used INTO lastRowMinus1Value FROM tempTable
WHERE ROWNUM = lastRowMinus1;

If anyone could give some guidance as to how to extract values in a more efficient way, I would really appreciate it.

UNION ALL will give a result with all rows from the first and second query combined. You can not store its result into a separate variable.

If you really want to use UNION ALL then following should be the approach:

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

Cheers!!

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

Test it online with db<>fiddle .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2025 STACKOOM.COM