oracle 有没有办法让sql查询循环通过一个数组,并将返回的每个视图堆叠到一个视图中?

svmlkihl  于 2022-11-22  发布在  Oracle
关注(0)|答案(2)|浏览(100)

我在Oracle DB中有如下SQL表:

我想从上表中得出以下观点:

我可以使用下面的查询生成视图的1行(在本例中为Item_id 'a')。

SELECT
    Item_ID,
    transaction_date as Latest_transaction
FROM
    (
        SELECT
            *
        FROM
            TABLE
        WHERE
            Item_id LIKE '%a%'
        ORDER BY
            transaction_date DESC
    )
WHERE
    ROWNUM = 1

我想对数组['a','B','d','e','z' ]中的每个值执行以下查询,然后通过UNION将每行追加到视图中。但是,我不确定如何执行此操作,因为SQL不能执行FOR循环。
我已经尝试运行一个对每个ID都有一个联合的大型查询,但是在我的实际用例中,有太多的Item_ID(~4k),SQL无法执行此查询。

SELECT
    Item_ID,
    transaction_date as Latest_transaction
FROM
    (
        SELECT
            *
        FROM
            TABLE
        WHERE
            Item_id LIKE '%a%'
        ORDER BY
            transaction_date DESC
    )
WHERE
    ROWNUM = 1
UNION
SELECT
    Item_ID,
    transaction_date as Latest_transaction
FROM
    (
        SELECT
            *
        FROM
            TABLE
        WHERE
            Item_id LIKE '%b%'
        ORDER BY
            transaction_date DESC
    )
WHERE
    ROWNUM = 1
...con't for all IDs.
sh7euo9m

sh7euo9m1#

WITH data(transaction_date, item_ids) AS (
    SELECT TO_DATE('10/11/2022','MM/DD/YYYY'), 'a;b;z' FROM DUAL UNION ALL
    SELECT TO_DATE('10/10/2022','MM/DD/YYYY'), 'a;d' FROM DUAL UNION ALL    
    SELECT TO_DATE('10/9/2022','MM/DD/YYYY'), 'a;b;d;z' FROM DUAL UNION ALL       
    SELECT TO_DATE('10/8/2022','MM/DD/YYYY'), 'z;e' FROM DUAL 
),
all_ids(id) AS (
    SELECT regexp_substr('a;b;d;e;g;z','[^;]+',1,LEVEL) FROM DUAL
    CONNECT BY regexp_substr('a;b;d;e;g;z','[^;]+',1,LEVEL) IS NOT NULL
),
expanded_ids AS (
    SELECT id, MAX(transaction_date) AS latest_transaction FROM (
        SELECT transaction_date, regexp_substr(item_ids,'[^;]+',1,LEVEL) AS id FROM data
        CONNECT BY regexp_substr(item_ids,'[^;]+',1,LEVEL) IS NOT NULL
            AND PRIOR transaction_date = transaction_date AND PRIOR sys_guid() IS NOT NULL
    )
    GROUP BY id
)
SELECT a.id, e.latest_transaction 
FROM all_ids a 
LEFT JOIN expanded_ids e ON e.id = a.id
ORDER BY id
;
osh3o9ms

osh3o9ms2#

您可以使用CTE和regexp_substr来完成此操作:

with transactions as
(
    select regexp_substr(tbl.Item_ids, '[^;]+', 1, level) Item_id
        , tbl.Transaction_date
    from tbl
    connect by level < length(replace(tbl.Item_ids, ';', '')) + 1
)
select Item_id
    , max(Transaction_date) Latest_transaction
from transactions
group by Item_id
order by Item_id

regexp_substr将允许您根据分隔符将字符串拆分为新行,然后我们将这些行作为最大值Transaction_date
然而,这只会给予你Item_ids中的字符,因为我假设这就是你所说的“数组”。如果你能澄清g结果来自哪里,我也可以在我的答案中包括它。

相关问题