结合两个已经工作的ORACLE查询

时间:2011-09-06 08:17:22

标签: sql oracle nested

我想请求以下两个查询的帮助。它们分别像魅力一样,现在我希望它们一起工作。

他们都提供会员卡数据库。

第一个根据用户的唯一卡号获取与用户相关的各种信息(%1111%%2222%%3333%在下面的示例中)并返回提供卡号的自定义订单中的行

SELECT cardnumber, first_name || ' ' || last_name 
FROM (
     SELECT cardnumber, first_name, last_name, c.OrderNo
     FROM ag_cardholder ch, (SELECT '%1111%' cardmask, 1 OrderNo from dual
                        UNION ALL
                        SELECT '%2222%', 2 OrderNo from dual
                        UNION ALL
                        SELECT '%3333%', 3 OrderNo from dual
                        ) c
     WHERE ch.cardnumber LIKE c.cardmask
     Order by c.OrderNo
) t

第二个代码根据卡号和最后用于在卡上写入点的终端类型返回卡的当前点余额两种类型的终端以不同方式计算实际余额(其中一个需要余额列中的数字,另一个需要总和 balance和total_points 列。)

SELECT *
FROM
(SELECT
cardnumber,
(SELECT last_name || ' ' || first_name FROM ag_cardholder WHERE cardnumber = '1111'),
CASE
WHEN terminal_id LIKE 'AGHUPR9%' THEN card_balance
WHEN terminal_id LIKE 'AGHUPR7%' THEN card_balance + total_points
END
FROM ag_tranzakcio
WHERE cardnumber = '1111'
ORDER BY tran_date DESC)
WHERE ROWNUM = 1

我想要的是是一个执行这两项任务的查询:以提供的顺序获取卡号,并以相同的顺序返回一些用户信息和当前余额。非常感谢您的帮助。

更新:不幸的是,我对ORACLE不太熟悉,甚至没有提出试错法解决方案,所以我现在依靠你的洞察力。

2 个答案:

答案 0 :(得分:1)

修订后的要求是仅返回每张卡的最新交易。这可以通过使用分析函数RANK()对事务进行排序,然后应用包装查询来过滤计算的排名来完成。

select cardnumber
       , card_holder
       , txn_amount
from 
    (
    SELECT ch.cardnumber
           , ch.first_name || ' ' || ch.last_name  as card_holder
           , CASE
                WHEN txn.terminal_id LIKE 'AGHUPR9%' THEN txn.card_balance
                WHEN txn.terminal_id LIKE 'AGHUPR7%' THEN txn.card_balance + txn.total_points
            END as txn_amount
           , rank () over (partition by ch.cardnumber order by txn.tran_date DESC) as rnk       
            , c.orderno
    FROM ag_cardholder ch
         join    (SELECT '%1111%' cardmask, 1 OrderNo from dual
                            UNION ALL
                            SELECT '%2222%', 2 OrderNo from dual
                            UNION ALL
                            SELECT '%3333%', 3 OrderNo from dual
                            ) c 
            on (ch.cardnumber LIKE c.cardmask)
         join ag_tranzakcio txn
            on (ch.cardnumber = txn.cardnumber)
    )        
where rnk=1       
order by orderno, cardnumber  
/

答案 1 :(得分:1)

SELECT cardnumber, name, balance, OrderNo
FROM
(
    SELECT 
    ch.cardnumber cardnumber, 
    ch.first_name || ' ' || ch.last_name name, 
    CASE WHEN t.terminal_id LIKE 'AGHUPR9%' THEN t.card_balance 
         WHEN t.terminal_id LIKE 'AGHUPR7%' THEN t.card_balance + t.total_points 
    END balance,
    rank () over (partition by ch.cardnumber order by t.tran_date DESC) rank,
    c.OrderNo as OrderNo
    FROM ag_cardholder ch
    JOIN (SELECT '%1111%' cardmask, 1 OrderNo from dual
                                UNION ALL
                                SELECT '%2222%', 2 OrderNo from dual
                                UNION ALL
                                SELECT '%3333%', 3 OrderNo from dual
                                ) c ON ch.cardnumber like c.cardmask
    JOIN ag_tranzakcio t ON ch.cardnumber = t.cardnumber 
)
WHERE rank = 1
ORDER BY OrderNo

编辑:假设ag_tranzakcio.id字段是一个可靠的递增键,这可能有效:

SELECT cardnumber, name, balance, OrderNo
FROM
(
    SELECT 
    ch.cardnumber cardnumber, 
    ch.first_name || ' ' || ch.last_name name, 
    CASE WHEN t.terminal_id LIKE 'AGHUPR9%' THEN t.card_balance 
         WHEN t.terminal_id LIKE 'AGHUPR7%' THEN t.card_balance + t.total_points 
    END balance,
    rank () over (partition by ch.cardnumber order by t.id DESC) rank,
    c.OrderNo as OrderNo
    FROM ag_cardholder ch
    JOIN (SELECT '%1111%' cardmask, 1 OrderNo from dual
                                UNION ALL
                                SELECT '%2222%', 2 OrderNo from dual
                                UNION ALL
                                SELECT '%3333%', 3 OrderNo from dual
                                ) c ON ch.cardnumber like c.cardmask
    JOIN ag_tranzakcio t ON ch.cardnumber = t.cardnumber 
)
WHERE rank = 1
ORDER BY OrderNo