用于打印从列A到列B

时间:2016-10-21 14:11:59

标签: sql oracle

SQL新手,寻求帮助

我正在尝试编写一个查询,该查询将打印从A列开始直到B列的值,不包括第二个表的“ANS”列中的值。

这里有两个表X和Y

    Table1  
A   FROM  TO
a   6     9
b   3     6
c   0     3
d   2     3

    Table2  
A   ANS 
a   7   
b   5   
c   1   

我希望输出为

A   ANS
a   6
a   8
a   9
b   3
b   4
b   6
c   0
c   2
c   3
d   2
d   3

我试过写这样的东西,但它不起作用

WITH y(n) AS 
(SELECT 1 AS n
FROM dual
UNION ALL
SELECT n + 1 AS n
FROM y, table1 T
WHERE n <= T.TO AND n>= T.FROM )
SELECT * FROM y;

打印5000多行(这就是我没有附加输出的原因) 提前致谢

3 个答案:

答案 0 :(得分:1)

使用递归cte获取from和to之间的所有数字后,在生成的表上左连接,并使用not exists仅获取table2中不存在的那些数字。

--Get the maximum value of `to` column and generate all numbers between 0 and that value
WITH maxto(maxt) as (SELECT MAX(TO) FROM TABLE1)
,y(n) AS 
(SELECT 0 AS n FROM dual
 UNION ALL
 SELECT n + 1 AS n FROM y WHERE n < (SELECT maxt FROM maxto)) 
SELECT * FROM
(SELECT t1.a, y.n
 FROM y
 LEFT JOIN table1 t1 on y.n between t1.from and t1.to 
 WHERE t1.a IS NOT NULL) x
WHERE NOT EXISTS (SELECT 1 FROM table2 WHERE x.a = a and x.n = ans)
ORDER BY 1,2

Sample demo

答案 1 :(得分:1)

WITH y(n) AS 
(SELECT level - 1 FROM dual connect by level <= select max(TO- FROM) +2 from table1)
SELECT t1.a, t1.from + y.n FROM table1 t1
         JOIN y on 1 = 1 
         left JOIN table2 on y.n + t1.FROM = t2.ANS and t2.a = t1.a
where y.n < t1.TO-t1.FROM  
  and t2.ANS is null;

答案 2 :(得分:1)

您可以使用“分层查询”和 $(document).ready(function () { // initialise the library and pass options var libraryObject = new WPCL.Library(); libraryObject.setup(customOptions); }); 操作,并完全避免加入。如果您对集合论有点熟悉,MINUS很容易理解。使用分层查询生成数字有点不自然(并且可能仅在Oracle中可用,我不知道任何其他数据库产品),但它经常使用并且它的工作速度非常快。

我将列名更改为MINUSfrom_n;我不记得“from”和/或“to”是否是Oracle中的保留字,但为什么要承担风险。

to_n

输出

with
     table1 ( a, from_n, to_n ) as (
       select 'a', 6, 9 from dual union all
       select 'b', 3, 6 from dual union all
       select 'c', 0, 3 from dual union all
       select 'd', 2, 3 from dual
     ),
    table2 ( a, ans ) as (  
       select 'a', 7 from dual union all
       select 'b', 5 from dual union all
       select 'c', 1 from dual
     )
-- everything above this point is for testing only and can be removed
-- solution (SQL query) begins below
select a, from_n + level - 1 as ans
  from table1
  connect by level <= 1 + to_n - from_n
      and prior a = a
      and prior sys_guid() is not null
minus
select a, ans 
  from table2
;