oracle 两个值之间的提取量

vqlkdk9b  于 2023-04-29  发布在  Oracle
关注(0)|答案(3)|浏览(196)

我有两个oracle表。
表A
| 金额|
| --------------|
| 两百|
| 五百|
| 一百|
表B
| 金额来源|金额至|批准人|
| --------------|--------------|--------------|
| - 一百|四九九|批准人1|
| 四百九十九|一千|批准人2|
| -50|三百|批准人3|
如果Oracle SQL从表A返回值200,那么它应该从表2中获取第一行(-100和499),从表A返回值500,那么它应该从表2中获取第二行(-499和1000),从表A返回值100,那么它应该从表2中获取第三行(-50和199)。
如果amount福尔斯amount_from & amount_to之间,其中最小,那么我需要找到相应的批准者。

ldfqzlk8

ldfqzlk81#

在Oracle 12中,您可以使用LATERAL连接并返回第一个匹配的行。

SELECT a.amount,
       b.approver
FROM   table_a a
       LEFT OUTER JOIN LATERAL (
         SELECT approver
         FROM   table_b b
         WHERE  a.amount BETWEEN b.amount_from AND b.amount_to
         ORDER BY
                amount_to - amount_from, -- Smallest range
                approver
         FETCH FIRST ROW ONLY
       ) b
       ON 1 = 1 -- Join condition is in the lateral query.

其中,对于样本数据:

CREATE TABLE table_a (Amount) AS
SELECT 200 FROM DUAL UNION ALL
SELECT 500 FROM DUAL UNION ALL
SELECT 100 FROM DUAL;

CREATE TABLE table_b (Amount_From, Amount_To, Approver) AS
SELECT -100,  499, 'Approver1' FROM DUAL UNION ALL
SELECT -499, 1000, 'Approver2' FROM DUAL UNION ALL
SELECT  -50,  300, 'Approver3' FROM DUAL;

输出:
| 金额|批准人|
| --------------|--------------|
| 两百|批准人3|
| 五百|批准人2|
| 一百|批准人3|
如果Oracle SQL从表A返回值200,那么它应该从表2中获取第一行(-100和499),从表A返回值500,那么它应该从表2中获取第二行(-499和1000),从表A返回值100,那么它应该从表2中获取第三行(-50和199)。
在SQL(在任何方言中,不仅仅是Oracle的SQL方言)中,没有“第一”或“第二”行的概念,除非您指定ORDER BY子句并可以定义结果集的确定性排序。
在这种情况下,你说你想要:
如果金额福尔斯amount_fromamount_to之间,这是最小的,那么我需要找到相应的批准人。
“最小”可以是最小的amount_from或最小的amount_toamount_fromamount_to之间的最小范围;我选择了最后一个度量,范围,但您同样可以实现任何其他度量来确定什么是“最小”。
fiddle

u5i3ibmn

u5i3ibmn2#

with tb as (
  select a.col_a, b.amount_from, b.amount_to, 
    row_number() over(partition by a.col_a order by b.amount_to) rn
  from tab_a a
  left join tab_b b on a.column_a between b.amount_from and b.amount_to 
)
select col_a, amount_from, amount_to
from tb
where rn=1;

严格按照你的“要求”,我会做上面的事情。尽管如此,就像同事们提到的那样,这是一个最不寻常的数据库设计。表应该有主键。最后是外键。我没有看到table_b的任何主键。数量区间看起来很奇怪,因为它们彼此相交-这是我在任何地方都没有看到的。..通常那些间隔不相交。

ekqde3dh

ekqde3dh3#

其中一个选项是使用解析函数Min()Over()建立表连接:

WITH        -- Sample data
    tbl_a (AMOUNT) AS
        (
            SELECT 200 FROM DUAL UNION ALL
            SELECT 500 FROM DUAL UNION ALL
            SELECT 100 FROM DUAL
        ),
    tbl_b (AMOUNT_FROM, AMOUNT_TO, APPROVER) AS
        (
            SELECT -100,  499, 'Approver1' FROM DUAL UNION ALL
            SELECT -499, 1000, 'Approver2' FROM DUAL UNION ALL
            SELECT  -50,  300, 'Approver3' FROM DUAL
        )
--  
--  Main SQL
SELECT AMOUNT, APPROVER 
FROM (   Select      a.AMOUNT,
                    Min(CASE  WHEN a.AMOUNT Between b.AMOUNT_FROM And b.AMOUNT_TO 
                              THEN b.AMOUNT_TO END) OVER(Partition By a.AMOUNT) "MIN_TO",
                    b.AMOUNT_FROM, b.AMOUNT_TO, b.APPROVER
        From        tbl_b b  
        Inner Join  tbl_a a ON( 1 = 1 )
     )
WHERE AMOUNT_TO = MIN_TO
--  
--  R e s u l t :
    AMOUNT APPROVER 
---------- ---------
       100 Approver3
       200 Approver3
       500 Approver2

相关问题