在具有两列的两个值之间进行选择

时间:2016-07-27 21:37:59

标签: sql oracle

大家好,我对这个有点难过,希望有人可以借给我一把。 我有一张这样的桌子。

CREATE TABLE ACCT (ACCT_FROM VARCHAR2(6) , ACCT_TO VARCHAR2(6) ); 

带有这些值

INSERT INTO ACCT VALUES ('2015', '2018');  
INSERT INTO ACCT VALUES ('2019');  
INSERT INTO ACCT (ACCT_FROM) VALUES ('2019');  

"ACCT_FROM" "ACCT_TO"
"2015"  "2018"
"2019"  ""

我正在尝试选择一个查询,该查询基本上会在帐户以2开头的位置之间提供from和to值。这只是一个更大的表的子集。所以我想最终得到像

这样的东西
ACCT
2015
2016
2017
2018
2019

我尝试了类似下面的内容,但我没有到达任何地方。

select acct_from  from ACCT where   
acct_from between '2000' and '2999'  
and (ACCT_FROM like '2%' or ACCT_TO like '2%') ; 

有人可以帮助我获得适当的结果。

感谢。

4 个答案:

答案 0 :(得分:2)

我有一个很好的适合你。我做了一些假设:varchar coloumn中的数据是数字。或者恰好是年数。所以发生了什么

with nrs as ( select rownum  +1999 nr from ( select 1 from dual group by cube (1,2,3,4,5,6,7,8,9,10) ) where rownum <= 1000 )

正在生成2000到2999之间的数字

联盟的第一部分使用它来显示acct_to和acct_from之间的所有数字,但只显示&#34; nr生成器&#34;中的数字。

union的第二部分添加了2000到2999之间的所有nrs,其中acct_from为null。

工会让你失去所有重复。

with nrs as ( select rownum  +1999 nr from ( select 1 from dual group by cube (1,2,3,4,5,6,7,8,9,10) ) where rownum <= 1000 )
select nrs.nr 
from   acct 
,      nrs
where  acct_to is not null
and    nrs.nr between to_number( acct_from ) and to_number( acct_to )
union 
select to_number(acct_from )
from   acct 
where  acct_to is null 
and    to_number(acct_from) between 2000 and 2999

答案 1 :(得分:1)

似乎想要这样的东西。这是一个奇怪的要求;也许你用“年”只是为了说明,但如果他们真的是年,如果一行有ACCT_FROM = 1997,ACCT_TO = 2003怎么办?结果集不应该包括2000年,2001年,2002年,2003年吗?

无论如何 - 以下解决方案可以满足您的要求;不是你可能要求的。如果这不是您所需要的,请澄清。

with
     acct ( acct_from, acct_to ) as (
       select '2015', '2018' from dual union all
       select '2019', null   from dual
     ),
     prep ( acct_2xxx ) as (
       select  to_number(acct_from)
         from  acct
         where acct_from like '2%'
       union all
       select  to_number(acct_to)
         from  acct
         where acct_to like '2%'
     ),
     acct_m ( acct_min, acct_max ) as (
       select min(acct_2xxx), max(acct_2xxx)
       from   prep
     )
select to_char(acct_min + level - 1) as acct_all
from   acct_m
connect by level <= acct_max - acct_min + 1
;

ACCT_ALL
----------------
2015
2016
2017
2018
2019

5 rows selected.

注意 - 我还假设您并不认真对表和另一个表中的列使用相同的名称(ACCT)。我没跟随你的领导。

答案 2 :(得分:0)

你正在寻找这个:

SELECT Val 
FROM
(
    SELECT ACCT_FROM AS Val FROM ACCT WHERE ACCT_FROM like '2%' 
    UNION
    SELECT ACCT_TO AS Val FROM ACCT  WHERE ACCT_TO like '2%' 
) T
ORDER BY Val

如果您想保留重复项,请将UNION更改为UNION ALL

答案 3 :(得分:0)

好的,我有答案。希望这有助于其他人。

with rangeOfAccounts(accounts, acct_to) as (
    select to_number(acct_from) as accounts,  to_number(ACCT_TO) as acct_to
    from acct where acct_from like '2%'
    union all
    select accounts + 1, ACCT_TO
    from rangeOfAccounts
    where accounts + 1 <= ACCT_TO
)
select accounts
from rangeOfAccounts
order by accounts