代码之家  ›  专栏  ›  技术社区  ›  Sarah Vessels

删除Oracle中的额外子查询,选择值数组

  •  0
  • Sarah Vessels  · 技术社区  · 16 年前

    我正在选择一些聚合数据,并对日期和特定字段进行分组。我希望显示该字段中的所有值以及这些值的计数,即使当天没有与该字段匹配的数据。例如。

    Date        MyField  Count
    2009-09-25  A        2
    2009-09-25  B        0
    2009-09-24  A        1
    2009-09-24  B        1
    

    Oracle SQL i当前必须执行以下操作:

    SELECT today,
           mytable.myfield,
           COUNT(
             CASE WHEN fields.myfield = mytable.myfield AND
                       date >= today AND
                       date < tomorrow
                  THEN 1
             END
           )
    FROM (
           SELECT TRUNC(SYSDATE) + 1 - LEVEL AS today,
                  TRUNC(SYSDATE) + 2 - LEVEL AS tomorrow
           FROM DUAL
           CONNECT BY LEVEL <= 30
         ),
         (
           /* This is the part that seems inefficient */
           SELECT DISTINCT myfield
           FROM mytable
           WHERE myfield IN ('A', 'B')
         ) fields,
         mytable
    GROUP BY today, mytable.myfield
    ORDER BY today DESC, mytable.myfield ASC
    

    我担心的是,我确切地知道要显示哪些值 myfield 而且似乎没有效率 SELECT 访问的查询 mytable .我想知道在这个子查询中是否有这样的方法:

    SELECT ('A', 'B') AS myfield
    FROM DUAL
    

    我使用的是旧版本的Oracle, WITH 条款不起作用。

    3 回复  |  直到 16 年前
        1
  •  1
  •   Jeremy Bourque    16 年前

    您必须将它们作为不同的行,而不是不同的列。所以你最终会

    select 'A' from dual
    union
    select 'B' from dual
    

    在这种情况下,只要在 mytable 字段“a”和“b”。如果没有,那么子查询将返回原始子查询不会返回的行。

        2
  •  0
  •   tuinstoel    16 年前

    为什么不升级您的Oracle版本?WITH子句首先添加到Oracle 9.2(2002)中。您仍在使用Oracle 8吗?

        3
  •  0
  •   APC    16 年前

    字段子查询和MyTable之间没有联接,因此结果集将包含 每一个 过去30天的MyField值。

    但是,为什么不放弃子查询,只对mytable.myfield进行筛选,而不添加该联接呢?此外,如果您关心性能,您应该在 WHERE 子句,否则将处理myTable中的每一行。

    select today
           , myfield
           , count ( case when trunc(somedate) = today then 1 end ) as ab_count
    from   ( select trunc(sysdate) + 1 - level as today
             from dual
             connect by level <= 30 )
           , mytable
    where myfield in ('A', 'B')
    and somedate >= trunc(sysdate) - 30
    group by today, myfield
    order by today desc, myfield asc
    /
    

    编辑

    我已经对一些测试数据运行了您的原始查询和修改后的查询。你只需相信我的话,两个结果实际上是相同的-或者你自己试试看:)

    您的查询返回:

    TODAY       M   AB_COUNT
    ----------- - ----------
    26-SEP-2009 A          0
    26-SEP-2009 B          0
    25-SEP-2009 A          2
    25-SEP-2009 B          2
    24-SEP-2009 A          2
    24-SEP-2009 B          0
    ...
    29-AUG-2009 A          1
    29-AUG-2009 B          2
    28-AUG-2009 A          1
    28-AUG-2009 B          0
    
    60 rows selected.
    
    SQL>
    

    我的查询返回:

    今天M ab ou count
    -----------------
    2009年9月26日A 0
    2009年9月26日B 0
    2009年9月25日A 2
    2009年9月25日B 2
    2009年9月24日A 2
    2009年9月24日B 0
    …
    2009年8月29日A 1
    2009年8月29日B 2
    2009年8月28日A 1
    2009年8月28日B 0
    
    选择了60行。
    
    SQL& GT;