高级SQL查询 - 通用临时表还是其他什么?

时间:2015-08-13 14:25:59

标签: sql oracle global temporary

我对Oracle SQL Queries相当新,遇到了一个我无法解决的问题,也没有很好地描述Google / StackOverflow的搜索栏以找到答案。

我有两张桌子。

为简单起见,假设表A有两个变量,这两个变量在表中都不是唯一的。

|Order |Feature|
|1     |      A|
|1     |      B|
|1     |      C|
|2     |      B|
|2     |      C|
|3     |      A|
|3     |      C|
|4     |      A|
|4     |      B|

表B包含Order变量和日期变量。在这种情况下,Order变量是唯一的。

|Order |     Date|
|1     |  Aug 1st|
|2     |  Aug 1st|
|3     |  Aug 1st|
|4     |July 31st|

这是棘手的部分(对我来说)。我想要表A,但没有任何命令:

  1. 不包含功能“A”的实例
  2. 表B中的八月份内
  3. 看起来像是:

    |Order |Feature|
    |1     |      A|
    |1     |      B|
    |1     |      C|
    |3     |      A|
    |3     |      C|
    

    我试图让它与全局本地表一起使用,但未成功。在该策略中,我首先将所有带有“A”的订单拉入表中,然后在临时表中使用订单拉出所有功能,并在8月份使用日期。

    或者,我假设没有临时表的方法更有效,但我的经验有限。

    有什么想法吗?

4 个答案:

答案 0 :(得分:1)

有几种方法可以实现这一点(使用GROUP BY,IN,EXISTS,ANY连接),这些方法都不需要临时表或类似的技术。

我选择了,因为它很容易理解。

Select order, feature 
From tableA a
WHERE a.Order  in (select order from TableA where Feature = 'A' )
and a.order in (select order from tableB where be extract(month from date) = 8  )

答案 1 :(得分:0)

我认为你必须做一个子查询来查找你的标准中的顺序,然后选择你想要的信息。

试试这个:

SELECT a.order, a.feature
FROM tableA a
INNER JOIN (SELECT DISTINCT a1.order
            FROM tableA a1 
            INNER JOIN tableB b 
                 ON b.order = a1.order
            WHERE month(b.date) = 8
                 AND a1.feature = 'A'
           ) c on c.order = a.order;

答案 2 :(得分:0)

我会通过使用分析函数来测试A' A的存在。功能,然后加入到另一个表中以获取dt。

正如你的问题所写,我认为这就是你所追求的:

with table_a as (select 1 ord, 'A' feature from dual union all
                 select 1 ord, 'B' feature from dual union all
                 select 1 ord, 'C' feature from dual union all
                 select 2 ord, 'B' feature from dual union all
                 select 2 ord, 'C' feature from dual union all
                 select 3 ord, 'A' feature from dual union all
                 select 3 ord, 'C' feature from dual union all
                 select 4 ord, 'A' feature from dual union all
                 select 4 ord, 'B' feature from dual),
     table_b as (select 1 ord, to_date('01/08/2015', 'dd/mm/yyyy') dt from dual union all
                 select 2 ord, to_date('01/08/2015', 'dd/mm/yyyy') dt from dual union all
                 select 3 ord, to_date('01/08/2015', 'dd/mm/yyyy') dt from dual union all
                 select 4 ord, to_date('31/07/2015', 'dd/mm/yyyy') dt from dual union all
                 select 5 ord, to_date('31/07/2015', 'dd/mm/yyyy') dt from dual),
         res as (select ta.ord,
                        ta.feature,
                        max(case when ta.feature = 'A' then 'A' end) over (partition by ta.ord) a_present,
                        tb.dt
                 from   table_a ta
                        inner join table_b tb on (ta.ord = tb.ord))
select ord,
       feature
from   res
where  a_present is not null
and    to_char(dt, 'mm') != '08';

       ORD FEATURE
---------- -------
         4 A      
         4 B

但是,您指出的结果表明您确实希望结果包含“A' A'在每个小组中确实属于8月份之内

with table_a as (select 1 ord, 'A' feature from dual union all
                 select 1 ord, 'B' feature from dual union all
                 select 1 ord, 'C' feature from dual union all
                 select 2 ord, 'B' feature from dual union all
                 select 2 ord, 'C' feature from dual union all
                 select 3 ord, 'A' feature from dual union all
                 select 3 ord, 'C' feature from dual union all
                 select 4 ord, 'A' feature from dual union all
                 select 4 ord, 'B' feature from dual),
     table_b as (select 1 ord, to_date('01/08/2015', 'dd/mm/yyyy') dt from dual union all
                 select 2 ord, to_date('01/08/2015', 'dd/mm/yyyy') dt from dual union all
                 select 3 ord, to_date('01/08/2015', 'dd/mm/yyyy') dt from dual union all
                 select 4 ord, to_date('31/07/2015', 'dd/mm/yyyy') dt from dual union all
                 select 5 ord, to_date('31/07/2015', 'dd/mm/yyyy') dt from dual),
         res as (select ta.ord,
                        ta.feature,
                        max(case when ta.feature = 'A' then 'A' end) over (partition by ta.ord) a_present,
                        tb.dt
                 from   table_a ta
                        inner join table_b tb on (ta.ord = tb.ord))
select ord,
       feature
from   res
where  a_present is not null
and    to_char(dt, 'mm') = '08';

       ORD FEATURE
---------- -------
         1 A      
         1 B      
         1 C      
         3 A      
         3 C  

答案 3 :(得分:0)

如果你对分析函数和子查询不满意(你应该,但你的问题表明你可能不是),你可以用直接连接做到这一点 - 没什么特别的:

SELECT a2.ord, a2.feature
FROM table_a a1 
inner join table_b b on b.ord = a1.ord 
inner join table_a a2 on a2.ord = a1.ord 
where b.dt between to_date('01-AUG-2015') and last_day(to_date('01-AUG-2015') + (86399/86400))
 and a1.feature = 'A';

基本上,你首先去表A获得有功能A的行,然后再去表A获得这些订单的所有行。

您的帖子没有说明一个订单是否可以两次使用相同的功能。我假设没有,但如果是,那么你需要SELECT DISTINCT而不是SELECT。

就个人而言,我可能会用上面描述的分析函数来编写它。我之所以添加这个替代方案只是因为它只使用非常基本的SQL。